Sequelize 是一个基于 Node.js 的 ORM 框架,让我们可以使用 JavaScript 对象操作数据库。然而在实际使用中,我们经常会遇到一些意外的错误,如数据库连接失败、表不存在、查询无结果等等。本文将详细介绍如何使用 Sequelize 处理这些异常,以及一些错误的处理指南。
错误分类
Sequelize 的错误可以分为两大类,一类是自定义的错误类型,如 SequelizeConnectionError、SequelizeValidationError,另一类是底层的 Node.js 异常,如 ECONNREFUSED、ETIMEDOUT 等。
自定义的错误类型
Sequelize 提供了多种自定义错误类型,每种类型用于描述不同的错误场景:
- SequelizeConnectionError:无法连接到数据库,如数据库地址错误、无法连接到网络等;
- SequelizeAccessDeniedError:数据库账号密码等鉴权信息错误;
- SequelizeUniqueConstraintError:违反了唯一性约束,如试图插入一个已存在的记录;
- SequelizeForeignKeyConstraintError:违反了外键约束,如试图删除一个存在关联记录的表;
- SequelizeRemoteError:远程数据库服务器发生异常;
- SequelizeTimeoutError:数据库操作超时;
- SequelizeValidationError:数据格式错误,如字段类型不正确、长度超出限制等。
Node.js 异常
在连接数据库或向数据库发送查询请求的过程中,可能会发生底层的 Node.js 异常,如 ECONNREFUSED、ETIMEDOUT 等。这些异常同样需要捕获和处理。
错误处理
在使用 Sequelize 进行数据库操作时,我们需要合理地处理可能出现的错误。以下是处理错误的几个最佳实践。
错误捕获
在使用 Sequelize 进行数据库操作时,必须捕获所有可能发生的异常。可以使用 try-catch 语句或 Promise 的 .catch() 方法来捕获异常。例如:
try {
const user = await User.create({ name: 'john', age: 30 })
} catch (error) {
console.error('创建用户失败', error)
}或者:
User.create({ name: 'john', age: 30 })
.then(user => console.log('用户创建成功'))
.catch(error => console.error('创建用户失败', error))错误处理器
Sequelize 可以通过 SequelizeOptions.logging 配置项设置默认的错误处理器。例如:
const sequelize = new Sequelize({
// ...
logging: function (message) {
console.error('Sequelize 错误:', message)
}
})在这个示例中,所有 Sequelize 抛出的异常都会被输出到控制台。
自定义错误处理
如果需要更细粒度地处理不同的异常,我们可以为每个操作自定义错误处理器。例如:
-- -------------------- ---- -------
------------- ----- ------- ---- -- --
---------- -- ----------------------
------------ -- -
-- ------ ---------- -------------------------- -
----------------------- ------
- ---- -- ------ ---------- -------------------------------- -
----------------------- ------
- ---- -
----------------------- ------
-
--在这个示例中,我们使用了 instanceof 判断异常类型,并分别处理了不同的异常。
自定义异常
有时候,我们需要自定义异常类型,并在程序中抛出该异常。可以使用以下代码创建自定义异常:
class CustomError extends Error {
constructor(message) {
super(message)
this.name = 'CustomError'
}
}接着就可以在程序中抛出该异常了:
throw new CustomError('这是一个自定义异常')异常传递
在使用 Sequelize 进行数据库操作时,异常会被传递到 Promise 链的 .catch() 方法。如果在该方法中未对异常进行处理,异常会继续传递到上一级 Promise 链,直至被处理为止。因此,一条 Promise 链中的任何一个操作出错都可能导致整个链断裂,异常无法正确传递。因此,在执行 Promise 链时,要确保链中每个操作都有自己的 .catch() 方法来捕获异常。
User.findOne({ where: { name: 'john' } })
.then(user => user.update({ age: 40 }))
.then(user => console.log('用户更新成功'))
.catch(error => console.error('更新用户失败', error))在这个示例中,如果查询用户失败或更新用户失败都会被捕获,避免整个 Promise 链断裂。
示例代码
以下是一个使用 Sequelize 创建用户的示例代码:
-- -------------------- ---- -------
----- - ---------- --------- - - --------------------
----- --------- - --- --------------------- ----------- ----------- -
----- ------------
-------- --------
-------- -------- --------- -
------------------------ ----- --------
-
--
----- ---- - ------------------------ -
----- -
----- -----------------
---------- -----
--
---- -
----- ------------------
---------- -----
-
--
----- -------- ------------ -
--- -
----- ---- - ----- ------------- ----- ------- ---- -- --
--------------------- --------------
- ----- ------- -
----------------------- ------
-
-
----- ---------------- ------ ---- --
----- ------------在执行该示例代码时,可以模拟不同的异常,如将数据库地址改为不存在的地址、将用户名设为重复值等,观察异常的输出和处理。
Source: FunTeaLearn,Please indicate the source for reprints https://funteas.com/post/67d82d7ca941bf7134e9f960