Jawaban lainnya sepenuhnya benar, tetapi jawaban ini memberikan beberapa detali ekstra, saya pikir.
Pertimbangkan contoh ini:
using System;
static class Program {
static void Main() {
try {
ThrowTest();
} catch (Exception e) {
Console.WriteLine("Your stack trace:");
Console.WriteLine(e.StackTrace);
Console.WriteLine();
if (e.InnerException == null) {
Console.WriteLine("No inner exception.");
} else {
Console.WriteLine("Stack trace of your inner exception:");
Console.WriteLine(e.InnerException.StackTrace);
}
}
}
static void ThrowTest() {
decimal a = 1m;
decimal b = 0m;
try {
Mult(a, b); // line 34
Div(a, b); // line 35
Mult(b, a); // line 36
Div(b, a); // line 37
} catch (ArithmeticException arithExc) {
Console.WriteLine("Handling a {0}.", arithExc.GetType().Name);
// uncomment EITHER
//throw arithExc;
// OR
//throw;
// OR
//throw new Exception("We handled and wrapped your exception", arithExc);
}
}
static void Mult(decimal x, decimal y) {
decimal.Multiply(x, y);
}
static void Div(decimal x, decimal y) {
decimal.Divide(x, y);
}
}
Jika Anda menghapus komentar throw arithExc;
baris, output Anda adalah:
Handling a DivideByZeroException.
Your stack trace:
at Program.ThrowTest() in c:\somepath\Program.cs:line 44
at Program.Main() in c:\somepath\Program.cs:line 9
No inner exception.
Tentu saja, Anda telah kehilangan informasi tentang di mana pengecualian itu terjadi. Jika sebaliknya Anda menggunakan throw;
garis, inilah yang Anda dapatkan:
Handling a DivideByZeroException.
Your stack trace:
at System.Decimal.FCallDivide(Decimal& d1, Decimal& d2)
at System.Decimal.Divide(Decimal d1, Decimal d2)
at Program.Div(Decimal x, Decimal y) in c:\somepath\Program.cs:line 58
at Program.ThrowTest() in c:\somepath\Program.cs:line 46
at Program.Main() in c:\somepath\Program.cs:line 9
No inner exception.
Ini jauh lebih baik, karena sekarang Anda melihat bahwa itu adalah Program.Div
metode yang menyebabkan masalah Anda. Tetapi masih sulit untuk melihat apakah masalah ini berasal dari baris 35 atau baris 37 di try
blok.
Jika Anda menggunakan alternatif ketiga, membungkus pengecualian luar, Anda tidak kehilangan informasi:
Handling a DivideByZeroException.
Your stack trace:
at Program.ThrowTest() in c:\somepath\Program.cs:line 48
at Program.Main() in c:\somepath\Program.cs:line 9
Stack trace of your inner exception:
at System.Decimal.FCallDivide(Decimal& d1, Decimal& d2)
at System.Decimal.Divide(Decimal d1, Decimal d2)
at Program.Div(Decimal x, Decimal y) in c:\somepath\Program.cs:line 58
at Program.ThrowTest() in c:\somepath\Program.cs:line 35
Khususnya Anda dapat melihat bahwa baris 35 yang mengarah ke masalah. Namun, ini mengharuskan orang untuk mencari InnerException
, dan rasanya agak tidak langsung untuk menggunakan pengecualian dalam kasus sederhana.
Dalam posting blog ini mereka mempertahankan nomor baris (garis blok coba) dengan memanggil (melalui refleksi) internal
metode intensi InternalPreserveStackTrace()
pada Exception
objek. Tetapi tidak baik menggunakan refleksi seperti itu (.NET Framework mungkin mengubah internal
anggota mereka suatu hari tanpa peringatan).