private static ICommandHandlerResult CreateDefaultLastChanceResult(ExceptionContext context) { Contract.Requires(context != null); if (context.ExceptionInfo == null) { return null; } Exception exception = context.ExceptionInfo.SourceException; CommandHandlerRequest request = context.Request; if (request == null) { return null; } ProcessorConfiguration configuration = request.Configuration; if (configuration == null) { return null; } ServicesContainer services = configuration.Services; Contract.Assert(services != null); return new ExceptionResult(exception, request); }
public async Task<HandlerResponse> ExecuteAsync(CancellationToken cancellationToken) { ExceptionDispatchInfo exceptionInfo; try { return await this.innerResult.ExecuteAsync(cancellationToken); } catch (Exception e) { exceptionInfo = ExceptionDispatchInfo.Capture(e); } // This code path only runs if the task is faulted with an exception Exception exception = exceptionInfo.SourceException; bool isCancellationException = exception is OperationCanceledException; ExceptionContext exceptionContext = new ExceptionContext(exceptionInfo, ExceptionCatchBlocks.ExceptionFilter, this.context); if (!isCancellationException) { // We don't log cancellation exceptions because it doesn't represent an error. await this.exceptionLogger.LogAsync(exceptionContext, cancellationToken); } CommandHandlerExecutedContext executedContext = new CommandHandlerExecutedContext(this.context, exceptionInfo); // Note: exception filters need to be scheduled in the reverse order so that // the more specific filter (e.g. Action) executes before the less specific ones (e.g. Global) for (int i = this.filters.Length - 1; i >= 0; i--) { IExceptionFilter exceptionFilter = this.filters[i]; await exceptionFilter.ExecuteExceptionFilterAsync(executedContext, cancellationToken); } if (executedContext.Response == null && !isCancellationException) { // We don't log cancellation exceptions because it doesn't represent an error. executedContext.Response = await this.exceptionHandler.HandleAsync(exceptionContext, cancellationToken); } if (executedContext.Response != null) { return executedContext.Response; } // Preserve the original stack trace when the exception is not changed by any filter. if (exception == executedContext.ExceptionInfo.SourceException) { exceptionInfo.Throw(); } else { // If the exception is changed by a filter, throw the new exception instead. executedContext.ExceptionInfo.Throw(); } throw Error.InvalidOperation(Resources.UnreachableCode); }
/// <summary> /// Initializes a new instance of the <see cref="ExceptionLoggerContext"/> class using the values provided. /// </summary> /// <param name="exceptionContext">The exception context.</param> public ExceptionLoggerContext(ExceptionContext exceptionContext) { if (exceptionContext == null) { throw Error.ArgumentNull("exceptionContext"); } this.exceptionContext = exceptionContext; }
/// <summary>Initializes a new instance of the <see cref="ExceptionHandlerContext"/> class.</summary> /// <param name="exceptionContext">The exception context.</param> public ExceptionHandlerContext(ExceptionContext exceptionContext) { if (exceptionContext == null) { throw new ArgumentNullException("exceptionContext"); } this.exceptionContext = exceptionContext; }
/// <summary>Calls an exception logger.</summary> /// <param name="logger">The unhandled exception logger.</param> /// <param name="context">The exception context.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>A task representing the asynchronous exception logging operation.</returns> public static Task LogAsync(this IExceptionLogger logger, ExceptionContext context, CancellationToken cancellationToken) { if (logger == null) { throw Error.ArgumentNull("logger"); } if (context == null) { throw Error.ArgumentNull("context"); } ExceptionLoggerContext loggerContext = new ExceptionLoggerContext(context); return logger.LogAsync(loggerContext, cancellationToken); }
/// <summary>Calls an exception handler and determines the response handling it, if any.</summary> /// <param name="handler">The unhandled exception handler.</param> /// <param name="context">The exception context.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns> /// A task that, when completed, contains the response message to return when the exception is handled, or /// <see langword="null"/> when the exception remains unhandled. /// </returns> public static Task<HandlerResponse> HandleAsync(this IExceptionHandler handler, ExceptionContext context, CancellationToken cancellationToken) { if (handler == null) { throw Error.ArgumentNull("handler"); } if (context == null) { throw Error.ArgumentNull("context"); } ExceptionHandlerContext handlerContext = new ExceptionHandlerContext(context); return HandleAsyncCore(handler, handlerContext, cancellationToken); }