编辑页面

错误

当对任何模型方法或助手进行调用失败时,Sails 会抛出一个 JavaScript Error 实例,其属性可用于诊断出错的原因。

Waterline 会规范化这些 Error 实例,使用一致的 err.name 值对其进行分类,并在适用时使用 err.code

try {
  await Something.create({…});
} catch (err) {
  // err.name
  // err.code
  // …
}

处理错误

#

全局错误处理虽然胜于无,但通常都不够。(“这不是一个有效的用户名”和“我们目前无法创建新用户”之间存在很大差异。)为了适当地处理不同类型的错误,您需要能够以细粒度的方式检查它们。

幸运的是,Sails 提供了一些语法糖来开箱即用地实现这一点,无需使用 try… catch:.intercept().tolerate()

await Something.create({…})
.intercept((err)=>{
 // Return a modified error here (or a special exit signal)
 // and .create() will throw that instead
 err.message = 'Uh oh: '+err.message;
 return err;
});
属性 类型 详情
name String 错误的广泛分类。

例如:'UsageError'
message String 参见 .message
stack String 参见 .stack
code String? 有时包含的更具体的错误分类。

例如:'E_UNIQUE'

当使用与 Waterline 交互的代码(通常通过模型方法)时,您可能会遇到几种不同的错误。

使用错误

#

当错误具有 name: 'UsageError' 时,这表示 Waterline 方法使用不正确,或使用无效的选项执行(例如,尝试创建违反模型 高级验证规则 之一的新记录)。

此类错误可能来自任何模型方法。

err.name === 'UsageError'

适配器错误

#

适配器错误通常表示底层适配器中存在问题,而不是请求本身。当数据库脱机时、存在权限问题时、由于某些特定于数据库的边缘情况,或者(更少见)适配器中的错误,都可能发生这种情况。此类错误将具有 name: 'AdapterError'

此类错误可能来自任何模型方法。

err.name === 'AdapterError'
E_UNIQUE
#

应该唯一的值与数据库中另一条记录的值匹配时,就会发生唯一性错误。虽然这被认为是适配器错误,但它有自己的 code 来将其与普通适配器错误区分开来:code: 'E_UNIQUE'

此类错误只能来自 .create().update().addToCollection().replaceCollection() 模型方法。

err.code === 'E_UNIQUE'

示例

#

在您的 Sails 应用程序中执行此操作的确切策略取决于您是否使用 await、Promise 或回调。

使用 await 处理错误
#

处理尝试从操作内部创建新用户时可能发生的各种错误

await User.create({ emailAddress: inputs.emailAddress })
// Uniqueness constraint violation
.intercept('E_UNIQUE', (err)=> {
  return 'emailAlreadyInUse';
})
// Some other kind of usage / validation error
.intercept({name:'UsageError'}, (err)=> {
  return 'invalid';
});
// If something completely unexpected happened, the error will be thrown as-is.

return exits.success();
使用回调或 Promise 链处理错误
#

如果您由于使用 Node.js <= v7.9 而无法使用 await,那么请做好准备:当使用回调或 Promise 链而不是 await 时,错误处理的工作方式略有不同。

如果可能,请使用 await!它对您的应用程序更安全,您的代码将更简洁,您也会更快乐。

例如,如果您使用 Promise 链,则可以使用以下方法处理尝试创建新用户时可能发生的各种错误

User.create({
  emailAddress: req.param('emailAddress')
})
.then(function (){
  res.ok();
})
// Uniqueness constraint violation
.catch({ code: 'E_UNIQUE' }, function (err) {
  res.sendStatus(409);
})
// Some other kind of usage / validation error
.catch({ name: 'UsageError' }, function (err) {
  res.badRequest();
})
// If something completely unexpected happened.
.catch(function (err) {
  res.serverError(err);
});

这是同一个示例,但使用传统的 Node.js 回调而不是 Promise 链编写

User.create({
  emailAddress: req.param('emailAddress')
})
.exec(function (err){
  if (err && err.code === 'E_UNIQUE') {
    return res.sendStatus(409);
  } else if (err && err.name === 'UsageError') {
    return res.badRequest();
  } else if (err) {
    return res.serverError(err);
  }

  return res.ok();
});

但请注意未捕获的异常

是否缺少内容?

如果您注意到我们遗漏了什么或可以改进的地方,请按照此链接并向 sails 存储库提交拉取请求。合并后,更改将在网站下次部署时反映出来。

概念