Praktik Terbaik - domain dan kode NSError untuk proyek / aplikasi Anda sendiri

114

Ada posting SO sebelumnya tentang menyiapkan domain kesalahan untuk kerangka kerja Anda sendiri, tetapi apa praktik terbaik terkait pengaturan domain kesalahan dan kode kesalahan khusus untuk proyek / aplikasi Anda sendiri ?

Misalnya, anggap Anda sedang mengerjakan aplikasi intensif Data Inti dengan banyak validasi, sebaiknya Anda tetap menggunakan kode kesalahan Data Inti "tidak tersedia di rak" (seperti NSManagedObjectValidationErrordari CoreDataErrors.h) atau Anda harus membuatnya sendiri MyAppErrors.hdan menentukan kesalahan dengan lebih spesifik (yaitu MyAppValidationErrorInvalidCombinationOfLimbs,?

Membuat domain kesalahan khusus dan sekumpulan kode kesalahan dapat membuat kode Anda tidak ambigu secara signifikan, tetapi apakah terlalu banyak overhead yang harus dipertahankan dan apakah seseorang harus khawatir tentang konflik penomoran kode kesalahan? Atau apakah ada masalah lain di sini?

Neal L
sumber

Jawaban:

152

Saya pribadi menggunakan domain gaya DNS terbalik. Sebagai contoh:

NSError * myInternalError = [NSError errorWithDomain:@"com.davedelong.myproject" code:42 userInfo:someUserInfo];

Bagian ketiga dari domain ( @"myproject") hanya digunakan untuk membedakan kesalahan dari proyek ini ( "My Project") dari kesalahan dalam proyek lain ( "My Other Project"=> com.davedelong.myotherproject).

Ini adalah cara sederhana untuk memastikan bahwa aku tidak akan konflik dengan kesalahan orang lain domain (jika saya menggunakan kode pihak ke-3), kecuali pengembang yang sengaja mencoba untuk main-main dengan hanya saya (yang saya percaya akan sangat tidak mungkin. ..).

Adapun konflik penomoran kode, jangan khawatir tentang itu. Selama kode itu unik dalam suatu domain , Anda akan baik-baik saja.

Adapun kesalahan menerjemahkan, itu terserah Anda. Apa pun yang Anda lakukan, pastikan Anda mendokumentasikannya dengan baik. Secara pribadi , saya biasanya hanya meneruskan kesalahan yang dihasilkan kerangka kerja saat mereka datang kepada saya, karena saya tidak pernah yakin bahwa saya akan menangani semua kode dan menerjemahkan semua userInfo menjadi sesuatu yang lebih spesifik untuk proyek saya. Kerangka kerja dapat mengubah dan menambahkan lebih banyak kode, atau mengubah arti kode yang ada, dll. Ini juga membantu saya secara lebih spesifik mengidentifikasi dari mana kesalahan itu berasal. Misalnya, jika kerangka kerja StackKit saya menghasilkan kesalahan di com.stackkitdomain, saya tahu itu masalah kerangka kerja. Namun, jika menghasilkan kesalahan dalam NSURLErrorDomain, maka saya tahu bahwa itu secara khusus berasal dari mekanisme pemuatan URL.

Apa yang dapat Anda lakukan adalah menangkap kesalahan yang dihasilkan kerangka kerja dan membungkusnya dalam objek kesalahan baru yang memiliki domain Anda dan kode generik, sesuatu seperti kFrameworkErrorCodeUnknownatau sesuatu, dan kemudian menempatkan kesalahan yang ditangkap di userInfobawah NSUnderlyingErrorKey. CoreData melakukan ini banyak (misalnya, jika Anda mencoba untuk save:sebuah NSManagedObjectContext, tetapi Anda memiliki kesalahan integritas hubungan, Anda akan mendapatkan error kembali tunggal, tetapi NSUnderlyingErrorKeyakan berisi lebih banyak informasi, seperti khusus yang hubungan yang salah, dll).

Dave DeLong
sumber
Karena apel juga menggunakan DNS terbalik, tampaknya cocok bagi orang lain untuk menggunakan gaya ini juga.
Johan Karlsson
36

Saya tidak memiliki cukup perwakilan untuk berkomentar, tetapi untuk jawaban yang diterima oleh Dave DeLong, mungkin lebih baik untuk digunakan [[NSBundle mainBundle] bundleIdentifier]daripada @"com.myName.myProject". Dengan cara ini, jika Anda mengubah nama atau nama proyek Anda, itu akan tercermin secara akurat.

Connor
sumber
4
Ide bagus. Jika Anda menggunakan Swift, Anda harus menggunakan opsional yang tidak dibungkus: NSBundle.mainBundle().bundleIdentifier!(jika Anda tahu pengenal bundel telah diatur, yang menurut saya kemungkinan besar)
Juul
Mengapa Anda ingin mencerminkan perubahan nama proyek di domain kesalahan?
zrslv
1
@zrxq Pasti ada manfaatnya memiliki domain kesalahan yang berbeda, tetapi bayangkan Anda salah mengeja proyek Anda atau Anda mengubah nama Anda dan ingin itu tercermin di mana-mana. Lebih baik mengaturnya secara dinamis daripada kode keras.
Connor
1
@vare Sudah jelas, saya tidak begitu mengerti manfaat praktis apa yang akan diberikannya. Pemahaman saya adalah pengenal tersebut hanya perlu unik dalam konteks aplikasi, itu saja. Oke, mungkin Anda hanya ingin mereka lebih estetis, saya mengerti!
zrslv
1
Ya, Anda mengemukakan poin yang bagus. Ada kalanya Anda ingin domain itu unik, saya akan berasumsi ... misalnya mungkin jika Anda membuat SDK atau (cocoa) Pod, Anda ingin domain kesalahan Anda mencerminkan dari mana asalnya, bukan proyeknya. nama. EDIT: Saya juga (dalam jawaban saya) ingin menunjukkan bahwa @ "com.myName.myProject" identik dengan bundleIdentifier dalam hal ini, yang mungkin tidak diketahui orang.
Connor
4

Cara membuat NSError kustom:

Pertama buat Kamus pesan kesalahan

NSDictionary *userInfo = @{   
   NSLocalizedDescriptionKey: NSLocalizedString(@"Unknown Error - Please try again", nil),
   NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"Unknown Error - Please try again", nil),
   NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Unknown Error - Please try again", nil)
                                               };
NSError *error = [NSError errorWithDomain:[[NSBundle mainBundle] bundleIdentifier] 
  code:-58 userInfo:userInfo];

Kemudian tetapkan userInfo ke NSDictionary dan selesai.

Mike Zriel
sumber