2015-02-12 14 views
5

Sto cercando di ottenere il mio servizio self-hosted utilizzando Nancy per restituire gli errori JSON formattati su un'eccezione non rilevata. Tuttavia, sto ottenendo sempre la risposta:NancyFX - Restituisce la risposta all'errore personalizzata sull'eccezione non rilevata

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

(qui di seguito è la fusione di diversi esempi attraverso la rete).

Il mio programma di avvio automatico contiene quanto segue:

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

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

Anche se ho verificato che il codice in OnError e Handle viene eseguito (vedi commenti), i miei clienti ricevere ancora 404. Ho anche provato a utilizzare

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

invece di

 var exception = context.GetException(); 

senza fortuna.

risposta

6

Gah, quindi questo era un problema CORS.

Sto aggiungendo automaticamente le intestazioni CORS alla risposta:

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

Ma quando la risposta è sostituito nel mio gestore codice di stato ho bisogno di impostare nuovamente queste intestazioni:

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