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
}
}
};
}
}