Dalam keadaan normal, jika pengecualian terjadi selama pemrosesan efek, itu akan ditangkap oleh onError yang didaftarkan oleh dva, dan pemrosesan umum dapat dilakukan di sini, yang sangat mudah digunakan.
Namun, setelah memutakhirkan dva2, saya menemukan sebuah fenomena (tidak muncul di dva1, atau situasi lain tidak diperhatikan pada saat itu) Ketika pengecualian dipicu, onError akan dimasukkan, tetapi pengecualian akan dilemparkan secara normal, menyebabkan konsol untuk menampilkan kesalahan.
Saya bukan front-end penuh waktu. Saya tidak tahu apakah situasi di atas disengaja. Jika ya, mohon beri tahu jika ada cara yang baik untuk mencegah pengecualian dilemparkan saat onError sedang diproses.
dva onError:
```skrip java
onError: (e) => {
console.log('onError', e)
}
any effect:
```java script
() => { throw Error('any error')}
Defaultnya adalah menangani secara diam-diam setelah penangkapan, tidak lagi melempar, jika Anda perlu melempar pengecualian lagi, Anda dapat melemparkannya sendiri di onError
cetak konsol:
Kesalahan onError: kesalahan apa pun ...
dan kesalahan konsol:
Tidak tertangkap (dalam janji) Kesalahan: kesalahan apa pun
dva 2.0.1
Memeriksanya.
Alasannya adalah bahwa di dva@2 , jika tindakan pengiriman adalah Efek, Janji akan dikembalikan. Dengan cara ini, panggilan balik pengiriman dapat ditangani di Component (#175 ), dan karena Component perlu menangani skenario penolakan Promise, kesalahan di sini tidak dapat diatasi oleh onError. .
dispatch({
type: 'effectAction'
})
.then(() => {})
.catch(() => {})
Kemudian Promise Rejection yang tidak tertangkap dikeluarkan melalui console.error, tetapi tidak menimbulkan kesalahan, sehingga tidak akan ditangkap oleh window.onerror, dan tidak berpengaruh pada pengguna.
Jika Anda tidak ingin melihat baris kesalahan ini, ada dua cara:
1> Tambahkan .catch
ke efek dispatch()
.catch
dispatch().catch(err => {});
2> Pantau secara global kejadian unhandledrejection dan cegah agar tidak dicetak melalui console.error.
window.addEventListener("unhandledrejection", function (event) {
event.preventDefault();
});
Terima kasih atas jawabannya, dampaknya terhadap pengguna tidak besar, terutama karena ada banyak masalah yang menyakitkan dalam proses pengembangan, seperti kode status http 4xx
, akan mencetak informasi pengecualian, dan kami menggunakannya dalam bereaksi skenario asli Dalam mode pengembangan, console.error
akan benar-benar memainkan kotak kuning...
Adapun dua metode pemrosesan ini:
catch
berarti semua kemungkinan kelainan memerlukan perawatan khusus, atau jika Anda secara aktif menyesuaikan onError
, Anda perlu mengulang kode, yang terasa kurang umumevent
yang dapat menelan pengecualianDengan berani mengusulkan ide setengah matang, di onError
Masuk resolve
dan reject
objek, onError
untuk memutuskan bagaimana menangani internal, atau dengan onError
Nilai kembalian
Anda tidak dapat melakukannya di onError
Waktu di Promise dan saga berbeda, yang akan menyebabkan onError
terpicu dua kali. Apa pendapat Anda tentang menambahkan onDispatchError
?
Balasannya cepat sekali, memang kalau di onError
, reject
akan masuk onError
...
Jika ada onDispatchError
, itu hanya digunakan untuk memproses action
untuk error
, jika benar-benar layak, jika Anda perlu membuangnya, cukup reject
, dan masukkan kembali catch
ditulis sendiri onError
Dengan kata lain, error
ini hanya akan memasukkan onDispatchError
, dan tidak akan memasukkan dua error handler
kan?
function *sagaWithCatch(...args) {
try {
yield sagaEffects.put({ type: `${key}${NAMESPACE_SEP}@@start` });
const ret = yield effect(...args.concat(createEffects(model)));
yield sagaEffects.put({ type: `${key}${NAMESPACE_SEP}@@end` });
resolve(key, ret);
} catch (e) {
onError(e);
reject(key, e);
}
}
Masalahnya adalah kode ini, kan? Saya memeriksa masalah ini dengan tuan rumah, dan secara pribadi berpikir ada dua cara untuk dipertimbangkan.
// 传 reject 进 onError
function *sagaWithCatch(...args) {
try {
yield sagaEffects.put({ type: `${key}${NAMESPACE_SEP}@@start` });
const ret = yield effect(...args.concat(createEffects(model)));
yield sagaEffects.put({ type: `${key}${NAMESPACE_SEP}@@end` });
resolve(key, ret);
} catch (e) {
onError(e, reject.bind(null, key, e)); // 把 redux middleware 产生的 promise 的 reject 给 onError ,由 onError 决定要不要触发这个 promise 的 catch 链
// 甚至可以把 resolve 都传进去,可以做到部分 error 处理后仍然正常执行 dispatch 的 then ,但感觉太奇怪了
}
}
// onError 返回一个 true/false
function *sagaWithCatch(...args) {
try {
yield sagaEffects.put({ type: `${key}${NAMESPACE_SEP}@@start` });
const ret = yield effect(...args.concat(createEffects(model)));
yield sagaEffects.put({ type: `${key}${NAMESPACE_SEP}@@end` });
resolve(key, ret);
} catch (e) {
const handled = onError(e);
if (!handled) reject(key, e); // onError 返回是否要继续抛出 error
}
}
Kembali benar dan salah juga terasa agak aneh. Dengan cara ini, berikan metode preventDefault untuk mencegah operasi penolakan berikutnya setelah eksekusi.
onError(e) {
e.preventDefault();
}
@sorrycc 👍 Nah, ini memang lebih masuk akal. Lagi pula, onError seharusnya tidak mengembalikan nilai secara semantik, dan arti spesifik dari benar/salah dari nilai yang dikembalikan tidak jelas.
Di tunggu rilisnya
Halo penulis @sorrycc , ada pertanyaan kecil, saya lebih bingung, saya memproses request.js secara seragam, kode status bukan 2xx, dan 3xx dioperasikan secara seragam oleh reject
, dan catch
ditentukan dalam pengiriman try catch
dalam efeknya untuk menangkap pengecualian. Saya pikir proses pengecualian pertama-tama akan melewati pengiriman catch
, ketika saya tidak memiliki catch
Saya berjalan ke onError
. Tapi sekarang saya langsung ke onError
, yang saya tahu adalah bahwa Anda dapat pergi ke try catch
berlaku, dan melakukan operasi reject
di catch
Selesaikan kebutuhan saya , tetapi setiap efek terasa aneh. Apakah perilaku ini memenuhi harapan Anda? Jika demikian, apa alasannya?
@ jinyang1994 Apakah sudah terpecahkan sekarang?
@jinyang1994 @dyf19118
Alasannya adalah bahwa di dva@2 , jika tindakan pengiriman adalah Efek, Janji akan dikembalikan. Dengan cara ini, panggilan balik pengiriman dapat ditangani di Component (#175 ), dan karena Component perlu menangani skenario penolakan Promise, kesalahan di sini tidak dapat diatasi oleh onError. .
Mengacu pada hal di atas, jika pengecualian yang dilempar ke dalam efek tidak tertangkap, onError akan dieksekusi, dan kemudian Janji yang dikembalikan oleh pengiriman akan diproses. Jika err. preventDefault()
dipanggil di onError, tangkapan pengiriman berikutnya tidak akan dieksekusi.
Mengirimkan efek, ada masalah dengan kode bisnis di dalamnya, saya tidak mencoba menangkap efeknya, dan halaman langsung macet. Saya ingin menangkap kesalahan melalui kenyamanan global tingkat atas untuk mencegah halaman mogok.
window.addEventListener("unhandledrejection", function (event) {
console.log('err.....,,,,', event)
event.preventDefault();
});
Kesalahan terdeteksi, tetapi halaman tetap macet. Bagaimana cara mencegah halaman mogok?
Komentar yang paling membantu
Kembali benar dan salah juga terasa agak aneh. Dengan cara ini, berikan metode preventDefault untuk mencegah operasi penolakan berikutnya setelah eksekusi.