One of the myriad of extension points that OpenRasta offers, is the operation interceptor. There’s a base class, called OperationInterceptor, that makes it convenient to override the method(s) you are interested in and provides a default (null) implementation for the others.
The IOperationInterceptor interface provides three methods:
- BeforeExecute: returns a boolean, allowing you to stop the pipeline. Useful for validation, for example.
- RewriteOperation
- AfterExecute: post-processing, also returns a boolean.
RewriteOperation is particularly interesting. The signature:
Func<IEnumerable<OutputMember>> RewriteOperation(Func<IEnumerable<OutputMember>> operationBuilder);
while a little frightening, reveals the intention. It’s basically a decorator, allowing you to wrap your operation with some other behaviour. Logging, for example, or exception handling.
public class ExceptionHandlerOperationInterceptor : OperationInterceptor { private readonly ILogger _logger; public ExceptionHandlerOperationInterceptor(ILogger logger) { _logger = logger; } public override Func<IEnumerable<OutputMember>> RewriteOperation(Func<IEnumerable<OutputMember>> operationBuilder) { return () => TryExecute(operationBuilder); } private IEnumerable<OutputMember> TryExecute(Func<IEnumerable<OutputMember>> operationBuilder) { try { return operationBuilder(); } catch (TargetInvocationException ex) { _logger.WriteException(ex.InnerException); return ReturnBadRequest(ex.InnerException); } } private static IEnumerable<OutputMember> ReturnBadRequest(Exception ex) { var errors = new List<Error> { new Error { Exception = ex, Message = ex.Message, } }; return new[] { new OutputMember { Value = new OperationResult.BadRequest { ResponseResource = new ErrorResource(), Errors = errors } } }; } }