Jak złapać wszystko nieobsłużone wyjątki występujące w ASP.NET Web Api, aby móc je rejestrować?
Do tej pory próbowałem:
- Utwórz i zarejestruj
ExceptionHandlingAttribute
- Zaimplementuj
Application_Error
metodę w programieGlobal.asax.cs
- Subskrybuj
AppDomain.CurrentDomain.UnhandledException
- Subskrybuj
TaskScheduler.UnobservedTaskException
ExceptionHandlingAttribute
Powodzeniem obsługuje wyjątków, które są generowane wewnątrz metod działania kontrolera i filtrów działania, ale inne wyjątki nie są obsługiwane, na przykład:
- Wyjątki zgłaszane, gdy wykonanie
IQueryable
zwrócone przez metodę akcji nie powiedzie się - Wyjątki zgłoszone przez program obsługi komunikatów (tj.
HttpConfiguration.MessageHandlers
) - Wyjątki zgłaszane podczas tworzenia instancji kontrolera
Zasadniczo, jeśli wyjątek spowoduje zwrócenie do klienta wewnętrznego błędu serwera 500, chcę, aby był on rejestrowany. Wdrożenie Application_Error
wykonało tę pracę dobrze w formularzach sieci Web i MVC - czego mogę używać w interfejsie Web Api?
c#
asp.net-web-api
unhandled-exception
Joe Daley
źródło
źródło
Odpowiedzi:
Jest to teraz możliwe dzięki WebAPI 2.1 (zobacz Co nowego ):
Utwórz jedną lub więcej implementacji IExceptionLogger. Na przykład:
Następnie zarejestruj się w HttpConfiguration aplikacji, wewnątrz wywołania zwrotnego konfiguracji, takiego jak:
lub bezpośrednio:
źródło
Odpowiedź Yuval dotyczy dostosowywania odpowiedzi na nieobsłużone wyjątki przechwycone przez interfejs API sieci Web, a nie do rejestrowania, jak wspomniano na połączonej stronie . Szczegółowe informacje można znaleźć w sekcji Kiedy używać na tej stronie. Rejestrator jest zawsze wywoływany, ale program obsługi jest wywoływany tylko wtedy, gdy można wysłać odpowiedź. Krótko mówiąc, użyj programu rejestrującego do logowania i modułu obsługi, aby dostosować odpowiedź.
Nawiasem mówiąc, używam zestawu v5.2.3, a
ExceptionHandler
klasa nie maHandleCore
metody. Myślę, że odpowiednik jestHandle
. Jednak zwykłe tworzenie podklasExceptionHandler
(jak w odpowiedzi Yuvala) nie działa. W moim przypadku muszę zaimplementowaćIExceptionHandler
w następujący sposób.Zauważ, że w przeciwieństwie do loggera, rejestrujesz program obsługi, zastępując domyślny program obsługi, a nie dodając.
źródło
Odpowiadając na moje własne pytanie, to niemożliwe!
Obsługa wszystkich wyjątków, które powodują wewnętrzne błędy serwera, wydaje się być podstawową funkcją, którą powinien mieć interfejs API sieci Web, więc wysłałem do firmy Microsoft żądanie do obsługi błędów globalnych dla interfejsu API sieci Web :
https://aspnetwebstack.codeplex.com/workitem/1001
Jeśli się zgadzasz, przejdź do tego linku i zagłosuj na to!
W międzyczasie doskonały artykuł dotyczący obsługi wyjątków interfejsu API sieci Web ASP.NET przedstawia kilka różnych sposobów przechwytywania kilku różnych kategorii błędów. Jest to bardziej skomplikowane niż powinno i nie obejmuje wszystkiego wyłapuje wewnętrznych błędów serwera, ale jest to najlepsze dostępne obecnie podejście.
Aktualizacja: Globalna obsługa błędów jest teraz zaimplementowana i dostępna w nocnych kompilacjach! Zostanie wydany w ASP.NET MVC v5.1. Oto jak to będzie działać: https://aspnetwebstack.codeplex.com/wikipage?title=Global%20Error%20Handling
źródło
Możesz również utworzyć globalną procedurę obsługi wyjątków, implementując
IExceptionHandler
interfejs (lub dziedziczącExceptionHandler
klasę bazową). Będzie to ostatnia wywołana w łańcuchu wykonania, po wszystkich zarejestrowanychIExceptionLogger
:Więcej na ten temat tutaj .
źródło
Możesz mieć istniejące bloki try-catch, o których nie jesteś świadomy.
Myślałem, że moja nowa
global.asax.Application_Error
metoda nie jest konsekwentnie wywoływana dla nieobsłużonych wyjątków w naszym starszym kodzie.Następnie znalazłem kilka bloków try-catch w środku stosu wywołań o nazwie Response.Write on the Exception. To było to. Porzucił tekst na ekranie, a następnie zabił kamień wyjątkowy martwy.
Tak więc wyjątki były obsługiwane, ale obsługa nie przyniosła żadnego pożytku. Po usunięciu tych bloków try-catch wyjątki propagowane do metody Application_Error zgodnie z oczekiwaniami.
źródło