2015-02-12 2 views
5

Я пытаюсь получить свою самообслуживаемую службу, используя Nancy, чтобы возвращать json-форматированные ошибки в результате неперехваченного исключения. Тем не менее, я всегда получаю ответ:NancyFX - Возвращает пользовательский ответ об ошибке на неперехваченное исключение

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

(ниже это объединение нескольких примеров по всей сети).

Мой Загрузчик содержит следующее:

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

У меня есть 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; 
    } 

Хотя я проверить, что код в OnError и Handle выполняется (см комментарии), мои клиенты все еще получают 404. Я также пробовал использовать

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

вместо

 var exception = context.GetException(); 

не повезло.

ответ

6

Gah, так что это проблема CORS.

Я автоматически добавлять заголовки CORS в ответ:

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

Но когда ответ заменен в моем статусе обработчика кода Мне нужно установить эти заголовки снова:

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"); 
    } 
} 
Смежные вопросы