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?