Latar Belakang
Saya mengembangkan Lapisan Layanan API untuk klien dan saya telah diminta untuk menangkap dan mencatat semua kesalahan secara global.
Jadi, sementara sesuatu seperti titik akhir yang tidak diketahui (atau tindakan) mudah ditangani dengan menggunakan ELMAH atau dengan menambahkan sesuatu seperti ini ke Global.asax
:
protected void Application_Error()
{
Exception unhandledException = Server.GetLastError();
//do more stuff
}
. . Kesalahan .unhandled yang tidak terkait dengan perutean tidak bisa login. Sebagai contoh:
public class ReportController : ApiController
{
public int test()
{
var foo = Convert.ToInt32("a");//Will throw error but isn't logged!!
return foo;
}
}
Saya juga telah mencoba mengatur [HandleError]
atribut secara global dengan mendaftarkan filter ini:
filters.Add(new HandleErrorAttribute());
Tapi itu juga tidak mencatat semua kesalahan.
Masalah / pertanyaan
Bagaimana cara mencegat kesalahan seperti yang dihasilkan oleh panggilan di /test
atas sehingga saya bisa mencatatnya? Tampaknya jawaban ini harus jelas, tetapi saya telah mencoba semua yang dapat saya pikirkan sejauh ini.
Idealnya, saya ingin menambahkan beberapa hal ke log kesalahan, seperti alamat IP pengguna yang meminta, tanggal, waktu, dan sebagainya. Saya juga ingin dapat mengirim email kepada staf pendukung secara otomatis ketika kesalahan terjadi. Semua ini bisa saya lakukan seandainya saya bisa mencegat kesalahan ini ketika itu terjadi!
TERSELESAIKAN!
Terima kasih kepada Darin Dimitrov, yang jawabannya saya terima, saya mengerti hal ini. WebAPI tidak menangani kesalahan dengan cara yang sama seperti pengontrol MVC biasa.
Inilah yang berhasil:
1) Tambahkan filter khusus ke namespace Anda:
public class ExceptionHandlingAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is BusinessException)
{
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent(context.Exception.Message),
ReasonPhrase = "Exception"
});
}
//Log Critical errors
Debug.WriteLine(context.Exception);
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
{
Content = new StringContent("An error occurred, please try again or contact the administrator."),
ReasonPhrase = "Critical Exception"
});
}
}
2) Sekarang daftarkan filter secara global di kelas WebApiConfig :
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{action}/{id}", new { id = RouteParameter.Optional });
config.Filters.Add(new ExceptionHandlingAttribute());
}
}
ATAU Anda dapat melewati pendaftaran dan hanya menghiasi satu pengontrol dengan [ExceptionHandling]
atribut.
sumber
Jawaban:
Jika API web Anda di-host di dalam aplikasi ASP.NET,Application_Error
acara tersebut akan dipanggil untuk semua pengecualian yang tidak ditangani dalam kode Anda, termasuk yang ada dalam tindakan uji yang telah Anda tunjukkan. Jadi yang harus Anda lakukan adalah menangani pengecualian ini di dalam acara Application_Error. Dalam kode sampel yang telah Anda tunjukkan, Anda hanya menangani pengecualian tipeHttpException
yang jelas tidak demikian denganConvert.ToInt32("a")
kode tersebut. Jadi pastikan Anda masuk dan menangani semua pengecualian di sana:Penanganan pengecualian di API Web dapat dilakukan di berbagai tingkatan. Berikut ini
detailed article
penjelasan berbagai kemungkinan:atribut filter pengecualian khusus yang dapat didaftarkan sebagai filter pengecualian global
penyerbu tindakan khusus
sumber
Application_Error
acara tersebut, ini berarti bahwa beberapa kode lain mengkonsumsinya sebelumnya. Misalnya, Anda mungkin memiliki beberapa HandleErrorAttributes kustom, modul khusus, ... Ada gazillions tempat lain di mana pengecualian dapat ditangkap dan ditangani. Tapi tempat terbaik untuk melakukannya adalah acara Application_Error, karena di situlah semua pengecualian yang tidak tertangani akan berakhir./test
contohnya tidak kena. Saya telah meletakkan breakpoint pada baris pertama (Exception unhandledException = . . .
) tetapi tidak bisa mengenai breakpoint itu dalam/test
skenario. Jika saya memasukkan url palsu, bagaimanapun, breakpoint terkena.Application_Error
acara bukan tempat yang tepat untuk menangani pengecualian untuk Web API karena tidak akan memicu dalam semua kasus. Saya telah menemukan artikel yang sangat rinci menjelaskan berbagai kemungkinan untuk mencapai itu: weblogs.asp.net/fredriknormen/archive/2012/06/11/…Sebagai tambahan untuk jawaban sebelumnya.
Kemarin, ASP.NET Web API 2.1 secara resmi dirilis .
Ini menawarkan kesempatan lain untuk menangani pengecualian secara global.
Rinciannya diberikan dalam sampel .
Secara singkat, Anda menambahkan log pengecualian global dan / atau handler pengecualian global (hanya satu).
Anda menambahkannya ke konfigurasi:
Dan realisasinya:
sumber
Mengapa rethrow dll? Ini berfungsi dan itu akan membuat status pengembalian layanan 500 dll
sumber
pernahkah Anda berpikir untuk melakukan sesuatu seperti filter tindakan penanganan kesalahan
Anda juga dapat membuat versi khusus untuk
[HandleError]
menulis info kesalahan dan semua detail lainnya untuk dicatatsumber
Bungkus semuanya dengan mencoba / menangkap dan mencatat pengecualian yang tidak tertangani, kemudian meneruskannya. Kecuali ada cara built-in yang lebih baik untuk melakukannya.
Berikut referensi Pengecualian Catch All (ditangani atau tidak ditangani)
(edit: oh API)
sumber