在此处理 REST API 调用的函数中,任何用于处理部分请求的被调用函数都可能引发错误,以表明应发送错误代码作为响应。但是,函数本身也可能发现错误,此时它应该跳转到异常处理 block 。
static async handleRequest(req) {
try {
let isAllowed = await checkIfIsAllowed(req);
if (!isAllowed) {
throw new ForbiddenException("You're not allowed to do that.");
}
let result = await doSomething(req); // can also raise exceptions
sendResult(result);
} catch(err) {
sendErrorCode(err);
}
}
Webstorm 将在 throw
下划线,并带有以下消息:'throw' of exception 在本地捕获。此检查报告任何 JavaScript throw 语句实例,其异常总是通过包含 try 语句来捕获。使用 throw 语句作为“goto”来更改本地控制流可能会令人困惑。
但是,我不确定如何重构代码来改善这种情况。
我可以将 catch
block 中的代码复制粘贴到 if
检查中,但我相信这会降低我的代码可读性和维护难度。
我可以编写一个新函数来执行 isAllowed
检查并在不成功时抛出异常,但这似乎是在回避问题,而不是解决 Webstorm 的设计问题据说是报道。
我们是否以错误的方式使用异常,这就是我们遇到此问题的原因,还是 Webstorm 错误只是误导并应该被禁用?
最佳答案
与 James Thorpe 的观点相反,我更喜欢 throw 的模式。我看不出有任何令人信服的理由来处理 try block 中的本地错误与从调用堆栈更深处冒出的错误有什么不同......只是抛出它们。在我看来,这是对一致性的更好应用。
因为这种模式更加一致,当您想将 try block 中的逻辑提取到可能在另一个模块/文件中的另一个函数时,它自然更适合重构。
// main.js
try {
if (!data) throw Error('missing data')
} catch (error) {
handleError(error)
}
// Refactor...
// validate.js
function checkData(data) {
if (!data) throw Error('missing data')
}
// main.js
try {
checkData(data)
} catch (error) {
handleError(error)
}
如果你处理错误而不是抛出 try block ,那么如果你在 try block 之外重构它,逻辑就必须改变。
另外,处理错误还有一个缺点,就是让你记得提前返回,这样try block 就不会在遇到错误后继续执行逻辑。这很容易忘记。
try {
if (!data) {
handleError(error)
return // if you forget this, you might execute code you didn't mean to. this isn't a problem with throw.
}
// more logic down here
} catch (error) {
handleError(error)
}
如果您担心哪种方法的性能更高,则不必担心。从技术上讲,处理错误的性能更高,但两者之间的差异绝对是微不足道的。
考虑一下 WebStorm 在这里有点过于固执的可能性。 ESLint 甚至没有为此制定规则。两种模式都是完全有效的。
关于javascript - 如何修复本地捕获的异常的 "' throw'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47015693/