Setiap kali saya perlu memberikan informasi tambahan tentang pengecualian saya bertanya-tanya di mana sebenarnya cara yang tepat untuk melakukan ini.
Demi pertanyaan ini, saya menulis sebuah contoh. Anggap ada kelas tempat kita ingin memperbarui Abbreviation
properti. Dari sudut pandang SOLID itu mungkin tidak sempurna tetapi bahkan jika kita melewati metode pekerja melalui DI dengan beberapa layanan situasi yang sama akan terjadi - pengecualian terjadi dan tidak ada konteks untuk itu. Kembali ke contoh ...
class Person
{
public int Id { get; set; }
public string Name { get; set; }
public string Abbreviation { get; set; }
}
Kemudian ada beberapa instance dari kelas dan loop di mana metode pekerja dipanggil. Itu bisa melempar StringTooShortException
.
var persons =
{
new Person { Id = 1, Name = "Fo" },
new Person { Id = 2, Name = "Barbaz" },
}
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
foreach (var person in persons)
{
try
{
person.Abbreviation = GenerateAbbreviation(person.Name);
}
catch(Exception ex)
{
// ?
}
}
// throw AggregateException...
}
public IEnumerable<string> GenerateAbbreviation(string value)
{
if (value.Length < 5)
{
throw new StringTooShortException(value);
}
// generate abbreviation
}
Pertanyaannya adalah: bagaimana cara menambahkan Person
atau nya Id
(atau apa pun)?
Saya tahu tiga teknik berikut:
1 - Gunakan Data
properti
Pro:
- mudah untuk mengatur informasi tambahan
- tidak perlu membuat lebih banyak pengecualian
- tidak memerlukan tambahan
try/catch
Kekurangan:
- tidak dapat dengan mudah diintegrasikan ke dalam
Message
- penebang mengabaikan bidang ini dan tidak akan membuangnya
- membutuhkan kunci dan casting karena nilai-nilai ini
object
- tidak kekal
Contoh:
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
foreach (var person in persons)
{
try
{
person.Abbreviation = GenerateAbbreviation(person.Name);
}
catch(Exception ex)
{
ex.Data["PersonId"] = person.Id;
// collect ex
}
}
// throw AggregateException...
}
2 - Gunakan properti khusus
Pro:
- mirip dengan
Data
properti tetapi sangat diketik - lebih mudah diintegrasikan ke dalam
Message
Kekurangan:
- membutuhkan pengecualian khusus
- logger akan mengabaikannya
- tidak kekal
Contoh:
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
foreach (var person in persons)
{
try
{
person.Abbreviation = GenerateAbbreviation(person.Name);
}
catch(Exception ex)
{
// not suitable for this exception because
// it doesn't have anything in common with the Person
}
}
// throw AggregateException...
}
3 - Bungkus pengecualian dengan pengecualian lain
Pro:
Message
dapat diformat dengan cara yang dapat diprediksi- penebang akan membuang pengecualian dalam
- abadi
Kekurangan:
- membutuhkan tambahan
try/catch
- menambah sarang
- meningkatkan kedalaman eksepsi
Contoh:
public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
foreach (var person in persons)
{
try
{
try
{
person.Abbreviation = GenerateAbbreviation(person.Name);
}
catch(Exception ex)
{
throw new InvalidPersonDataException(person.Id, ex);
}
}
catch(Exception ex)
{
// collect ex
}
}
// throw AggregateException...
}
- Apakah ada pola lain?
- Apakah ada pola yang lebih baik?
- Bisakah Anda menyarankan praktik terbaik untuk salah satu dari mereka?
sumber
Jawaban:
Data
FTW ."Kontra" Anda:
-> Untuk jenis pengecualian Anda , itu harus cukup mudah untuk ditimpa
Message
sehingga tidak tergabungData
.. meskipun saya hanya akan mempertimbangkan ini jikaData
pesannya .Googling untuk Nlog sebagai contoh menghasilkan :
Jadi sepertinya itu mudah dikonfigurasi.
Hah? Cukup buang benda-benda di sana dan pastikan mereka memiliki yang dapat digunakan
ToString()
metode yang digunakan.Juga, saya tidak melihat masalah dengan kunci. Cukup gunakan keunikan ringan dan Anda baik-baik saja.
Penafian: Ini adalah apa yang saya dapat segera lihat dari pertanyaan dan apa yang saya googled
Data
dalam 15 menit. Saya pikir ini agak membantu, jadi saya mengeluarkannya sebagai jawaban, tetapi saya tidak pernah menggunakanData
diri saya sendiri, jadi mungkin saja si penanya di sini tahu lebih banyak tentang hal ini daripada saya.sumber
Mengapa Anda melempar Pengecualian? Agar mereka ditangkap dan ditangani.
Bagaimana cara kode penangkapan mengetahui cara menangani Pengecualian? Menggunakan properti yang Anda tetapkan pada objek Pengecualian.
Jangan pernah menggunakan properti Pesan untuk mengidentifikasi pengecualian, atau untuk memberikan "informasi" yang harus diandalkan oleh penangan potensial. Itu terlalu mudah berubah dan tidak dapat diandalkan.
Saya tidak pernah menggunakan properti "Data" sebelumnya tetapi kedengarannya terlalu generik bagi saya.
Kecuali jika Anda membuat banyak kelas Pengecualian, yang masing-masing mengidentifikasi kasus Luar Biasa tertentu , bagaimana Anda tahu kapan Anda menangkap Pengecualian yang diwakili oleh "Data"? (Lihat komentar sebelumnya tentang "Pesan").
sumber
Data
tidak berguna untuk penanganan, tetapi berharga untuk logging untuk menghindariMessage
pemformatan neraka.Saya suka contoh ketiga Anda, namun ada cara lain yang bisa dikodekan untuk menghilangkan sebagian besar "con" Anda.
sumber