I've implemented a custom correlation ID strategy. I first check to see if there is a Correlation-ID header present in a request. If there isn't, I create a correlation ID. Then I assign the correlation ID to a NancyContext.Items entry.
The issue I'm running into is with the OnError pipeline. In my browsing of NancyFx's source code, I was unable to find a place to modify the response generated by my OnError handler. That means I am unable to add a Correlation-ID response header. The AfterRequest pipeline does not exhibit this same limitation.
// Fails because context.Response is null
context.Response.WithHeader("Correlation-ID", correlationId.Value.ToString("D"));
One possible design would be to call the AfterRequest pipeline after the OnError pipeline has executed, and pass the delegate a value that allows AfterRequest handlers to determine if there was an error (perhaps pass the relevant Exception, or null?)
N/A
N/A
Using http://bytefish.de/blog/consistent_error_handling_with_nancy as a guide, I managed to work around this with this implementation:
protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
{
var responseNegotiator = container.Resolve<IResponseNegotiator>();
pipelines.BeforeRequest.AddItemToEndOfPipeline(BeforeRequestProcessCorrelationIds);
pipelines.AfterRequest.AddItemToEndOfPipeline(AfterRequestProcessCorrelationIds);
pipelines.OnError.AddItemToEndOfPipeline((context, exception) => OnErrorWrapInErrorEnvelope(context, exception, responseNegotiator));
base.ApplicationStartup(container, pipelines);
}
private static dynamic OnErrorWrapInErrorEnvelope(NancyContext context, Exception exception, IResponseNegotiator responseNegotiator)
{
Log.Error(exception, "An unhandled exception occurred.");
var responseModel = new ErrorResponseModel
{
Exception = CreateExceptionModel(exception),
Message = "An unhandled exception occurred."
};
Response response = responseNegotiator.NegotiateResponse(responseModel, context);
AddCorrelationIdsToResponse(context, response);
return response;
}
Most helpful comment
Using http://bytefish.de/blog/consistent_error_handling_with_nancy as a guide, I managed to work around this with this implementation: