Quelle est la manière appropriée d'implémenter un gestionnaire d'attrape-gestionnaire d'exception global dans une implémentation Katana (OWIN)?
Dans une implémentation OWIN/Katana auto-hébergée s'exécutant en tant que service cloud Azure (rôle de travail), j'ai placé ce code dans un middleware:
throw new Exception("pooo");
Ensuite, j'ai placé ce code dans la méthode de configuration de la classe de démarrage, en définissant un point d'arrêt dans le gestionnaire d'événements:
AppDomain.CurrentDomain.UnhandledException +=
CurrentDomain_UnhandledExceptionEventHandler;
et le gestionnaire d'événements de la même classe (avec un point d'arrêt défini sur la première ligne):
private static void CurrentDomain_UnhandledExceptionEventHandler(object sender, UnhandledExceptionEventArgs e)
{
var exception = (Exception)e.ExceptionObject;
Trace.WriteLine(exception.Message);
Trace.WriteLine(exception.StackTrace);
Trace.WriteLine(exception.InnerException.Message);
}
Lorsque le code est exécuté, le point d'arrêt n'est pas touché. La fenêtre de sortie de Visual Studio inclut cependant ceci:
A first chance exception of type 'System.Exception' occurred in redacted.dll
A first chance exception of type 'System.Exception' occurred in mscorlib.dll
J'ai également essayé de déplacer le wireup et le gestionnaire vers la méthode OnStart du rôle du travailleur, mais le point d'arrêt n'est toujours pas atteint.
Je n’utilise pas du tout WebAPI, mais j’ai jeté un coup d’œil aux articles sur ce qui s’y fait, mais je n’ai rien trouvé de clair, alors je suis là.
Fonctionnant sur .NET Framework 4.5.2, VS 2013.
Toutes les idées appréciées. Merci.
Essayez d’écrire un middleware personnalisé et de le placer comme middleware first:
public class GlobalExceptionMiddleware : OwinMiddleware
{
public GlobalExceptionMiddleware(OwinMiddleware next) : base(next)
{}
public override async Task Invoke(IOwinContext context)
{
try
{
await Next.Invoke(context);
}
catch(Exception ex)
{
// your handling logic
}
}
}
Placez-le en tant que middleware first:
public class Startup
{
public void Configuration(IAppBuilder builder)
{
var config = new HttpConfiguration();
builder.Use<GlobalExceptionMiddleware>();
//register other middlewares
}
}
Lorsque nous enregistrons ce middleware en tant que premier milieu, toute exception se produisant dans d'autres middlewares (en bas de la pile) se propagera et sera interceptée par le bloc try/catch
de ce middleware.
Il n'est pas obligatoire de toujours l'enregistrer en tant que premier middleware. Si vous n'avez pas besoin de la gestion globale des exceptions pour certains middlewares, il vous suffit d'enregistrer ces middlewares avant celui-ci.
public class Startup
{
public void Configuration(IAppBuilder builder)
{
var config = new HttpConfiguration();
//register middlewares that don't need global exception handling.
builder.Use<GlobalExceptionMiddleware>();
//register other middlewares
}
}
Essaye ça:
public class CustomExceptionHandler : IExceptionHandler
{
public Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
// Perform some form of logging
context.Result = new ResponseMessageResult(new HttpResponseMessage
{
Content = new StringContent("An unexpected error occurred"),
StatusCode = HttpStatusCode.InternalServerError
});
return Task.FromResult(0);
}
}
Et au démarrage:
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
config.Services.Replace(typeof(IExceptionHandler), new CustomExceptionHandler());
}
Ответ @Khanh TO отличный; Ороший краткий код, и хорошо объяснил.
То не работает для меня. Добавил тестовое исклчение к одному из моих контроллеров .NET MVC, maintenant:
throw new Exception("Test GlobalExceptionMiddleware");
Cliquez ici pour en savoir plus sur Invoke
name__.
То очень легко отладить:
Для меня был добавлен код к BaseController
name__, переопредялему OnException
name__. Тот код обрабатывал исключение et 2 ans Cliquez ici pour en savoir plus sur les événements de @Khanh TO.
Хорошо, я понимаю, что этот вопрос помечен с помощью API Web, и мой вариант использования .NET MVC, но я нашел этот вопрос при поиске промежуточного программного обеспечения Owin. Когда ÿ отлаживаю свое решение с тестовым исключением Ø наблюдаю $exception
 представлении sections locales, исключение пропало , когда я возвращаюсь к промежуточному программному обеспечению Owin. Поэтому я не использовал код в ответе @Khanh TO. Cliquez ici pour afficher/télécharger/essayer par le démarrage (Startup) et Global.asax. Меня также есть OnException
в моем базовом контроллере, как то:
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled)
{
return;
}
var e = filterContext.Exception;
Log.Error("BaseController.OnException caught exception:", e);
filterContext.ExceptionHandled = true;
}
Vous êtes le premier à donner votre avis sur cet objet Того достаточно для моих нужд.