javascript - 如何修复本地捕获的异常的 "' throw'?

标签 javascript node.js rest exception-handling async-await

在此处理 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/

相关文章:

用于检测不活动或离开用户的 Javascript

javascript - ExtJS 5 - 从商店动态添加项目到拆分按钮菜单

javascript - 使用 Vue 的搜索框和复选框过滤器

javascript - 这段代码有什么问题,它说listen EADDRINUSE : address already in use 127. 0.0.1:8080

java - Jersey 2 - ContainerRequestFilter 获取方法注解

node.js - REST API 安全性。 SSL 还是 OAuth2?

java - 使用矩阵参数执行 Get 请求?

javascript - 更改另一个 div 鼠标悬停上的多个 div 内容,无需 css/使用 xml 源文件

mysql - Node.JS/MySQL - 错误 : connect ECONNREFUSED - happening at random

javascript - 无法并行运行 Selenium PhantomJS 实例