/// <summary> /// If a request cannot be completed by <see cref="Handle"/>, implementing the <see cref="Fallback"/> method provides an alternate code path that can be used /// This allows for graceful degradation. Using the <see cref="FallbackPolicyAttribute"/> handler you can configure a policy to catch either all <see cref="Exception"/>'s or /// just <see cref="BrokenCircuitException"/> that occur later in the pipeline, and then call the <see cref="Fallback"/> path. /// Note that the <see cref="FallbackPolicyAttribute"/> target handler might be 'beginning of chain' and need to pass through to actual handler that is end of chain. /// Because of this we need to call Fallback on the chain. Later step handlers don't know the context of failure so they cannot know if any operations they had, /// that could fail (such as DB access) were the cause of the failure chain being hit. /// Steps that don't know how to handle should pass through. /// Useful alternatives for Fallback are to try via the cache. /// Note that a Fallback handler implementation should not catch exceptions in the <see cref="Fallback"/> chain to avoid an infinite loop. /// Call <see cref="Successor"/>.<see cref="Handle"/> if having provided a Fallback you want the chain to return to the 'happy' path. Excerise caution here though /// as you do not know who generated the exception that caused the fallback chain. /// For this reason, the <see cref="FallbackPolicyHandler"/> puts the exception in the request context. /// When the <see cref="FallbackPolicyAttribute"/> is set on the <see cref="Handle"/> method of a derived class /// The <see cref="FallbackPolicyHandler{TRequest}"/> will catch either all failures (backstop) or <see cref="BrokenCircuitException"/> depending on configuration /// and call the <see cref="RequestHandler{TRequest}"/>'s <see cref="Fallback"/> method /// </summary> /// <param name="command">The command.</param> /// <returns>TRequest.</returns> public virtual TRequest Fallback(TRequest command) { if (_successor != null) { Logger.DebugFormat("Falling back from {0} to {1}", Name, _successor.Name); return(_successor.Fallback(command)); } return(command); }
/// <summary> /// If a request cannot be completed by <see cref="Handle"/>, implementing the <see cref="Fallback"/> method provides an alternate code path that can be used /// This allows for graceful degradation. Using the <see cref="FallbackPolicyAttribute"/> handler you can configure a policy to catch either all <see cref="Exception"/>'s or /// just <see cref="BrokenCircuitException"/> that occur later in the pipeline, and then call the <see cref="Fallback"/> path. /// Note that the <see cref="FallbackPolicyAttribute"/> target handler might be 'beginning of chain' and need to pass through to actual handler that is end of chain. /// Because of this we need to call Fallback on the chain. Later step handlers don't know the context of failure so they cannot know if any operations they had, /// that could fail (such as DB access) were the cause of the failure chain being hit. /// Steps that don't know how to handle should pass through. /// Useful alternatives for Fallback are to try via the cache. /// Note that a Fallback handler implementation should not catch exceptions in the <see cref="Fallback"/> chain to avoid an infinite loop. /// Call <see cref="Successor"/>.<see cref="Handle"/> if having provided a Fallback you want the chain to return to the 'happy' path. Excerise caution here though /// as you do not know who generated the exception that caused the fallback chain. /// For this reason, the <see cref="FallbackPolicyHandler{TRequest}"/> puts the exception in the request context. /// When the <see cref="FallbackPolicyAttribute"/> is set on the <see cref="Handle"/> method of a derived class /// The <see cref="FallbackPolicyHandler{TRequest}"/> will catch either all failures (backstop) or <see cref="BrokenCircuitException"/> depending on configuration /// and call the <see cref="RequestHandler{TRequest}"/>'s <see cref="Fallback"/> method /// </summary> /// <param name="command">The command.</param> /// <returns>TRequest.</returns> public virtual TRequest Fallback(TRequest command) { if (_successor != null) { s_logger.LogDebug("Falling back from {HandlerName} to {NextHandler}", Name, _successor.Name); return(_successor.Fallback(command)); } return(command); }