如何修复“'抛出'本地捕获的异常”?

新手上路,请多包涵

在这个处理 REST API 调用的函数中,任何被调用的处理请求部分的函数都可能抛出错误,以表示应发送错误代码作为响应。但是,函数本身也可能发现错误,此时它应该跳转到异常处理块。

 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 caught locally. This inspection reports any instances of JavaScript throw statements whose exceptions are always caught by containing try statements. Using throw statements as a "goto" to change the local flow of control is likely to be confusing.

但是,我不确定如何重构代码来改善这种情况。

我可以将 catch 块中的代码复制粘贴到 if 检查中,但我相信这会降低我的代码的可读性和维护难度。

我可以编写一个新函数来执行 isAllowed 检查并在不成功时抛出异常,但这似乎是在回避问题,而不是解决 Webstorm 应该报告的设计问题。

我们是否以错误的方式使用异常,这就是我们遇到此问题的原因,或者 Webstorm 错误只是误导并应该被禁用?

原文由 cib 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 3k
2 个回答

您正在检查某些内容并在 isAllowed 失败时抛出异常,但您知道在那种情况下该怎么做 - 调用 sendErrorCode 。如果您不知道如何处理这种情况,您应该向外部调用者抛出异常——即在特殊情况下。

在这种情况下,您已经定义了发生这种情况时该怎么做的流程 - 只需直接使用它而无需间接抛出/捕获:

 static async handleRequest(req) {
    try {
        let isAllowed = await checkIfIsAllowed(req);
        if (!isAllowed) {
            sendErrorCode("You're not allowed to do that.");
            return;
        }
        let result = await doSomething(req); // can also raise exceptions
        sendResult(result);
    } catch(err) {
        sendErrorCode(err);
    }
}

我可以将 catch 块中的代码复制粘贴到 if 检查中,但我相信这会降低我的代码的可读性和维护难度。

相反,如上所述,我希望这是处理这种情况的方法。

原文由 James Thorpe 发布,翻译遵循 CC BY-SA 3.0 许可协议

与 James Thorpe 的观点相反,我更喜欢投掷的模式。我没有看到任何令人信服的理由来处理 try 块中的本地错误与从调用堆栈的更深处冒出的错误有任何不同……只是抛出它们。在我看来,这是一个更好的一致性应用。

因为这种模式更加一致,所以当您想将 try 块中的逻辑提取到可能位于另一个模块/文件中的另一个函数时,它自然更适合重构。

 // 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 块,那么如果您在 try 块之外重构它,则逻辑必须改变。

另外,处理错误的缺点是让你记得早点返回,这样try块就不会在遇到错误后继续执行逻辑。这很容易忘记。

 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 甚至没有这方面的规则。两种模式都是完全有效的。

原文由 J. Munson 发布,翻译遵循 CC BY-SA 4.0 许可协议

推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏