Saya mencoba untuk memperpanjang Kesalahan dengan ES6 dan Babel. Itu tidak berhasil.
class MyError extends Error {
constructor(m) {
super(m);
}
}
var error = new Error("ll");
var myerror = new MyError("ll");
console.log(error.message) //shows up correctly
console.log(myerror.message) //shows empty string
Objek Kesalahan tidak pernah mendapatkan pesan yang benar ditetapkan.
Sekarang saya telah melihat beberapa solusi pada SO ( misalnya di sini ), tetapi mereka semua tampak sangat un-ES6-y. Bagaimana cara melakukannya dengan cara ES6 yang bagus? (Itu bekerja di Babel)
javascript
ecmascript-6
babeljs
transpiler
Karel Bílek
sumber
sumber
Jawaban:
Berdasarkan jawaban Karel Bílek, saya akan membuat perubahan kecil pada
constructor
:Ini akan mencetak
MyError
dalam tumpukan, dan bukan generikError
.Itu juga akan menambahkan pesan kesalahan ke jejak tumpukan - yang hilang dari contoh Karel.
Ini juga akan digunakan
captureStackTrace
jika tersedia.Dengan Babel 6, Anda perlu transform-builtin- extended ( npm ) agar bisa berfungsi.
sumber
if (typeof Error.captureStackTrace === 'function') { Error.captureStackTrace(this, this.constructor.name) } else { this.stack = (new Error(message)).stack; }
. Saya berpendapat bahwa lebih baik menggunakan fungsi ini jika tersedia, karena menyediakan stack panggilan yang lebih 'asli' dan mencetak nama objek kesalahan. Tentu saja, jika Anda menggunakan ini hanya pada sisi-server juga (Node), maka itu juga tidak masalah.this.stack = (new Error(message)).stack
Anda mendapatkan itu ... tetapi dalam praktiknya, ini mungkin bukan masalah besar.new MyError('foo') instanceof MyError === false
extendable-error-class
npmjs.com/package/extendable-error-class yang nyaman untuk menghindari ketergantungan pada babel-plugin-transform-builtin-this.message = message;
berlebihan dengansuper(message);
Menggabungkan jawaban ini , jawaban ini dan kode ini , saya telah membuat kelas "pembantu" kecil ini, yang sepertinya berfungsi dengan baik.
Coba di REPL
sumber
this.stack = (new Error(message)).stack;
- kalau tidak, pesannya hilang dari stacktracemessage
di konstruktor Error stack, sehingga ia menunjukkan pesan yang tepat di bagian atas stack ketika dilemparkan:this.stack = (new Error(message)).stack;
myerror.name
sekarang mengembalikan "Kesalahan". Tidak yakin apakah ini terkait dengan versi babel nanti. Lihat jawaban @ sukima di bawah iniAkhirnya meletakkan ini untuk beristirahat. Di Babel 6 itu adalah eksplisit bahwa pengembang tidak mendukung membentang dari dibangun di. Meskipun trik ini tidak akan membantu dengan hal-hal seperti
Map
,Set
, dll tidak bekerja untukError
. Ini penting karena salah satu ide inti dari suatu bahasa yang dapat menimbulkan pengecualian adalah mengizinkan kesalahan khusus. Ini sangat penting karena Janji menjadi lebih berguna karena mereka dirancang untuk menolak Kesalahan .Kebenaran yang menyedihkan adalah Anda masih perlu melakukan ini dengan cara lama di ES2015.
Contoh dalam Babel REPL
Pola Kesalahan Khusus
Di sisi lain ada plugin untuk Babel 6 untuk memungkinkan ini.
https://www.npmjs.com/package/babel-plugin-transform-builtin-extend
Pembaruan: (per 2016-09-29) Setelah beberapa pengujian tampak bahwa babel.io tidak memperhitungkan dengan benar semua pernyataan (memperluas dari Kesalahan yang diperluas khusus). Namun dalam Ember.JS, memperpanjang Kesalahan berfungsi seperti yang diharapkan: https://ember-twiddle.com/d88555a6f408174df0a4c8e0fd6b27ce
sumber
Error.toString()
. Kebutuhan untuk melakukan simpangan dan putaran khusus untuk mencapai hal ini berarti sebagian besar devs akan menghindarinya dan melakukan praktik-praktik buruk seperti melempar string, bukannya Kesalahan. Atau membuat Peta sendiri seperti objek. Mengapa perlu untuk menghalangi metode OOP seperti itu?Sunting : Memecah perubahan dalam naskah 2.1
Mengedit jawaban asli Lee Benson sedikit bermanfaat bagi saya. Ini juga menambah
stack
dan metode tambahanExtendableError
kelas ke instance.sumber
Object.setPrototypeOf
dalamMyError
konstruktor juga. stackoverflow.com/a/41102306/186334 github.com/Microsoft/TypeScript-wiki/blob/master/…Dengan perubahan terbaru dalam babel 6, saya menemukan transform-builtin-extended tidak lagi berfungsi. Saya akhirnya menggunakan pendekatan campuran ini:
dan
Akibatnya semua tes ini lulus:
sumber
Mengutip
Meskipun kode di atas tidak dapat menampilkan jejak stack kecuali
this.stack = (new Error()).stack;
atauError.captureStackTrace(this, this.constructor.name);
dipanggil dalam Babel . IMO, mungkin ada satu masalah di sini.Sebenarnya, jejak stack bisa menjadi output di bawah
Chrome console
danNode.js v4.2.1
dengan potongan kode ini.Output dari
Chrome console
.Output dari
Node.js
sumber
Selain jawaban @ zangw, Anda dapat menentukan kesalahan Anda seperti ini:
yang akan membuang nama, pesan, dan stacktrace yang benar:
sumber
new MyError('foo') instanceof MyError === false
.Node.js v7.7.3
.Bahwa
class MyError extends Error {…}
sintaks benar.Perhatikan bahwa transpiler masih memiliki masalah dengan pewarisan dari objek bawaan. Dalam kasus anda,
tampaknya memperbaiki masalah.
sumber
Error.call()
mengembalikan contoh kesalahan baru untuk saya.Mengingat ini jawaban yang diterima tidak lagi bekerja Anda selalu bisa menggunakan pabrik sebagai alternatif ( repl ):
sumber
Saya lebih suka sintaks yang lebih kuat daripada yang dijelaskan di atas. Metode tambahan pada tipe kesalahan akan membantu Anda membuat cantik
console.log
atau sesuatu yang lain.Untuk menguji kode ini, Anda dapat menjalankan sesuatu yang serupa:
Perluasan
CustomError
jenis dipersilakan. Dimungkinkan untuk menambahkan beberapa fungsi spesifik ke tipe yang diperluas atau menimpa yang sudah ada. Sebagai contoh.sumber
Seperti @sukima menyebutkan, Anda tidak dapat memperpanjang JS asli. Pertanyaan OP tidak dapat dijawab.
Mirip dengan jawaban Melbourne2991 , saya memang menggunakan pabrik, tetapi mengikuti rekomendasi MDN untuk jenis kesalahan pelanggan .
sumber
Ini bekerja untuk saya:
sumber
Tidak menggunakan Babel, tetapi di ES6 biasa, berikut ini sepertinya berfungsi dengan baik untuk saya:
Pengujian dari REPL:
Seperti yang Anda lihat, tumpukan berisi nama kesalahan dan pesan. Saya tidak yakin apakah saya kehilangan sesuatu, tetapi semua jawaban lain tampaknya terlalu rumit.
sumber
Saya sedikit memperbaiki solusi @Lee Benson dengan cara ini:
extendedableError.js
contoh kesalahan
Kemudian Anda dapat mengelompokkan kesalahan sambil memiliki opsi penentu untuk memutuskan apa yang harus dilakukan secara berbeda dalam beberapa situasi spesifik aplikasi Anda
sumber