-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dva2 onError 处理的异常仍然抛出 #1222
Comments
排查了下。 原因是在 dva@2 中,如果 dispatch 的 action 是一个 Effect,会返回 Promise。这样就可以在 Component 中处理 dispatch 的回调 ( #175 ),而由于 Component 里会需要处理 Promise 的 reject 场景,所以这里的错误不能被 onError 吞掉。。 dispatch({
type: 'effectAction'
})
.then(() => {})
.catch(() => {}) 然后未捕获的 Promise Rejection 就通过 console.error 输出,但并不是抛错,所以也不会被 window.onerror 捕获到,对用户无影响。 如果不想看到这行错误,有两个办法: 1> 给 effect 的 dispatch().catch(err => {}); 2> 全局监听 unhandledrejection 事件,并阻止通过 console.error 打印出。 window.addEventListener("unhandledrejection", function (event) {
event.preventDefault();
}); |
多谢回复, 对用户影响倒是不大, 主要是开发过程中有很多比较蛋疼的问题, 比如 至于这两种处理方法:
大胆的提出一个不成熟的想法, 在 |
放 |
回复好快啊, 确实如果在 |
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);
}
} 问题是这段代码吧?我和楼主一起查的这个问题,个人觉得有两种方式可以考虑。 // 传 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
}
} |
return true 和 false 感觉也有点奇怪。这样吧,提供 preventDefault 方法,执行后就阻止后续的 reject 操作。 onError(e) {
e.preventDefault();
} |
@sorrycc 👍 嗯 确实这样更合理,毕竟 onError 语义上不太应该返回一个值,而且返回值的 true / false 具体意义也不明。 坐等 release 😄 |
@sorrycc 作者您好,有一个小问题,我比较有困惑,我在request.js中统一处理,状态码不是2xx,3xx的统一进行 |
@jinyang1994 现在有解决了嘛 |
参考上面说的,如果 effects 中抛异常没有被捕获,会执行 onError,然后才是 dispatch 返回的 Promise 处理。如果在 onError 中调用 |
dispatch一个effect,里面的业务代码出现了问题,我没有在effect里面try catch,结果页面直接崩溃了,想通过一个顶层的全局方便来捕捉错误,防止页面崩溃。
错误是捕获到了,但是页面还是崩溃了,我该怎么防止页面崩溃呢 |
onError 捕获异常后, 异常仍然被抛出
正常情况下在 effect 处理时发生异常, 会被 dva 注册的 onError 捕获到, 在此可以做通用处理, 非常好用.
但是升级 dva2 之后发现一个现象(dva1 时没有出现, 或者是其他情况当时没有注意), 异常触发时会进 onError, 但是异常一样会被正常抛出, 导致 console 输出 error
Code to reproduce the issue: (请提供可复现的代码或者步骤)
dva onError:
any effect:
Expected behavior: (预期的正常效果)
默认捕获后静默处理, 不再抛出, 如果需要再抛出异常, 可在 onError 自行 throw
Actual behavior: (实际效果)
console print:
onError Error: any error ...
and console error:
Uncaught (in promise) Error: any error
Versions of packages used: (哪个库的哪个版本出现的问题)
dva 2.0.1
The text was updated successfully, but these errors were encountered: