Apa cara yang benar untuk menangani kesalahan dengan streaming? Saya sudah tahu ada acara 'kesalahan' yang bisa Anda dengarkan, tetapi saya ingin tahu lebih banyak detail tentang situasi rumit yang sewenang-wenang.
Sebagai permulaan, apa yang Anda lakukan ketika ingin melakukan rantai pipa sederhana:
input.pipe(transformA).pipe(transformB).pipe(transformC)...
Dan bagaimana Anda benar membuat salah satu dari transformasi itu sehingga kesalahan ditangani dengan benar?
Pertanyaan terkait lainnya:
- ketika kesalahan terjadi, apa yang terjadi pada acara 'akhir'? Apakah tidak pernah dipecat? Apakah kadang-kadang dipecat? Apakah ini tergantung pada transformasi / aliran? Apa standarnya di sini?
- apakah ada mekanisme untuk menyebarkan kesalahan melalui pipa?
- apakah domain menyelesaikan masalah ini secara efektif? Contohnya akan menyenangkan.
- apakah kesalahan yang keluar dari peristiwa 'kesalahan' memiliki jejak tumpukan? Terkadang? Tidak pernah? apakah ada cara untuk mendapatkannya dari mereka?
Promise
kerangka kerja membuatnya lebih sederhanaJawaban:
mengubah
Transform stream dapat dibaca dan ditulis, dan karenanya benar-benar bagus 'stream tengah'. Karena alasan ini, mereka kadang-kadang disebut sebagai
through
stream. Mereka mirip dengan aliran duplex dengan cara ini, kecuali mereka menyediakan antarmuka yang bagus untuk memanipulasi data daripada hanya mengirimkannya. Tujuan dari aliran transformasi adalah untuk memanipulasi data saat disalurkan melalui aliran. Anda mungkin ingin melakukan beberapa panggilan async, misalnya, atau menurunkan beberapa bidang, memetakan beberapa hal, dll.Untuk cara membuat aliran transformasi lihat di sini dan di sini . Yang harus Anda lakukan adalah:
_transform
metode yang membutuhkan a(chunk, encoding, callback)
.Potongan adalah data Anda. Sebagian besar waktu Anda tidak perlu khawatir tentang penyandian jika Anda bekerja
objectMode = true
. Callback dipanggil saat Anda selesai memproses chunk. Potongan ini kemudian didorong ke aliran berikutnya.Jika Anda menginginkan modul pembantu yang bagus yang akan memungkinkan Anda melakukan melalui aliran dengan sangat mudah, saya sarankan through2 .
Untuk penanganan kesalahan, terus membaca.
pipa
Dalam rantai pipa, penanganan kesalahan memang tidak mudah. Menurut utas ini .pipe () tidak dibangun untuk meneruskan kesalahan. Jadi sesuatu seperti ...
... hanya akan mendengarkan kesalahan pada aliran
c
. Jika acara kesalahan dipancarkana
, itu tidak akan diturunkan dan, pada kenyataannya, akan melempar. Untuk melakukan ini dengan benar:Sekarang, meskipun cara kedua lebih bertele-tele, Anda setidaknya bisa menjaga konteks di mana kesalahan Anda terjadi. Ini biasanya hal yang baik.
Satu perpustakaan saya menemukan membantu jika Anda memiliki kasus di mana Anda hanya ingin menangkap kesalahan di tempat tujuan dan Anda tidak begitu peduli tentang di mana itu terjadi adalah event-stream .
akhir
Ketika acara kesalahan dipecat, acara akhir tidak akan dipecat (secara eksplisit). Memancarkan peristiwa kesalahan akan mengakhiri aliran.
domain
Dalam pengalaman saya, sebagian besar domain berfungsi dengan sangat baik. Jika Anda memiliki peristiwa kesalahan yang tidak ditangani (yaitu memancarkan kesalahan pada aliran tanpa pendengar), server dapat macet. Sekarang, seperti yang ditunjukkan artikel di atas, Anda dapat membungkus aliran dalam domain yang seharusnya menangkap semua kesalahan.
Keindahan domain adalah bahwa mereka akan melestarikan jejak tumpukan. Meskipun event-stream melakukan pekerjaan dengan baik juga.
Untuk bacaan lebih lanjut, lihat stream-handbook . Cukup mendalam, tetapi sangat berguna dan memberikan beberapa tautan bagus ke banyak modul bermanfaat.
sumber
.on('error')
pawang dalam fungsi anonim yaitua.on('error', function(e){handleError(e)})
hanya bisaa.on('error', handleError)
Jika Anda menggunakan simpul> = v10.0.0 Anda dapat menggunakan stream.pipeline dan stream.finished .
Sebagai contoh:
Lihat PR github ini untuk diskusi lebih lanjut.
sumber
finished
, ketikapipeline
sudah memiliki panggilan balik?domain tidak digunakan lagi. kamu tidak membutuhkannya.
untuk pertanyaan ini, perbedaan antara transformasi atau tulisan tidak begitu penting.
Jawaban mshell_lauren bagus, tetapi sebagai alternatif Anda juga dapat secara eksplisit mendengarkan acara kesalahan pada setiap aliran yang menurut Anda mungkin salah. dan gunakan kembali fungsi penangan jika Anda mau.
melakukan hal itu untuk mencegah pengecualian yang tidak tertangkap yang terkenal itu jika salah satu dari mereka menembakkan kesalahannya
sumber
error
, orang mungkin juga puas dengan fakta bahwa setiap peristiwa berbeda; 2) streaming streaming apa yang ditulis di atas, selain fungsionalitas Node.js asli? dan 3) mengapa tidak masalah bagaimana mereka menangani acara secara internal, ketika ini jelas memungkinkan siapa pun untuk melampirkan penangan kesalahan tambahan di atas apa pun yang sudah ada di sana?Kesalahan dari seluruh rantai dapat diperbanyak ke aliran paling kanan menggunakan fungsi sederhana:
yang bisa digunakan seperti:
sumber
.on("error", handler)
hanya menangani kesalahan Stream tetapi jika Anda menggunakan Transform stream kustom,.on("error", handler)
jangan tangkap kesalahan yang terjadi di dalam_transform
fungsi. Jadi orang dapat melakukan sesuatu seperti ini untuk mengendalikan aliran aplikasi: -this
kata kunci dalam_transform
fungsi mengacu padaStream
dirinya sendiri, yang merupakanEventEmitter
. Jadi Anda dapat menggunakantry catch
seperti di bawah ini untuk menangkap kesalahan dan kemudian meneruskannya ke penangan acara khusus.Dengan cara ini, Anda dapat menjaga logika dan penangan kesalahan Anda terpisah. Anda juga dapat memilih untuk menangani hanya beberapa kesalahan dan mengabaikan yang lain.
UPDATE
Alternatif: RXJS diamati
sumber
Gunakan paket multipipe untuk menggabungkan beberapa aliran menjadi satu aliran dupleks. Dan menangani kesalahan di satu tempat.
sumber
Gunakan pola Node.js dengan membuat mekanisme Transform stream dan memanggil panggilan baliknya
done
dengan argumen untuk menyebarkan kesalahan:sumber
Coba tangkap tidak akan menangkap kesalahan yang terjadi di aliran karena karena mereka dilemparkan setelah kode panggilan sudah keluar. Anda dapat merujuk ke dokumentasi:
https://nodejs.org/dist/latest-v10.x/docs/api/errors.html
sumber