NancyFX - returns a custom error response to an uncaught exception

I am trying to get my self-service service using Nancy to return json-formatted errors in an uncovered exception. However, I always get the answer:

{"readyState":4,"status":404,"statusText":"error"} 

(below is a combination of several examples over the network).

My boot file contains the following:

  pipelines.OnError.AddItemToEndOfPipeline((ctx, exc) => { if (exc is Exception) { // this is always executed upon failure to handle an exception. Log.Error("Unhandled error on request: " + context.Request.Url + " : " + exc.Message, exc); JsonResponse response = new JsonResponse(string.Format("{0}:{1}", exc, exc.Message), new DefaultJsonSerializer()); response.StatusCode = HttpStatusCode.InternalServerError; return response; } return HttpStatusCode.InternalServerError; }); 

I have a StatusCodeHandler:

 public class JsonErrorStatusCodeHandler : IStatusCodeHandler { public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context) { return statusCode == HttpStatusCode.InternalServerError; } public void Handle(HttpStatusCode statusCode, NancyContext context) { var exception = context.GetException(); if (exception != null) { // never executed } // this is executed JsonResponse response = new JsonResponse("wtf"), new DefaultJsonSerializer()); response.StatusCode = HttpStatusCode.InternalServerError; context.Response = response; } 

Although I checked that the code in OnError and Handle is executing (see comments), my clients still get 404. I also tried using

  var exception = context.Items[NancyEngine.ERROR_EXCEPTION] as Exception; 

instead

  var exception = context.GetException(); 

no luck.

+5
source share
1 answer

Gah, so this is a CORS problem.

I automatically add CORS headers to the response:

  protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context) { pipelines.AfterRequest.AddItemToEndOfPipeline((ctx) => { ctx.Response.WithHeader("Access-Control-Allow-Origin", "*") .WithHeader("Access-Control-Allow-Methods", "POST,GET") .WithHeader("Access-Control-Allow-Headers", "Accept, Origin, Content-type"); }); pipelines.OnError.AddItemToEndOfPipeline((ctx, exc) => { if (exc != null) { throw exc; } return HttpStatusCode.InternalServerError; }); base.RequestStartup(container, pipelines, context); } 

But when the response is replaced in my status code handler, I need to set these headers again:

 public class JsonErrorStatusCodeHandler : IStatusCodeHandler { public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context) { if (statusCode != HttpStatusCode.InternalServerError) { return false; } var exception = context.GetException(); return exception != null; } public void Handle(HttpStatusCode statusCode, NancyContext context) { var exception = context.GetException(); JsonResponse response = new JsonResponse(string.Format("{0}:{1}", exception, exception.Message), new DefaultJsonSerializer()); response.StatusCode = HttpStatusCode.InternalServerError; context.Response = response; context.Response.WithHeader("Access-Control-Allow-Origin", "*") .WithHeader("Access-Control-Allow-Methods", "POST,GET") .WithHeader("Access-Control-Allow-Headers", "Accept, Origin, Content-type"); } } 
+6
source

Source: https://habr.com/ru/post/1213274/


All Articles