在 API 开发过程中,异常处理是一个十分重要且不可避免的问题。而 Hapi.js 是目前比较热门的 Node.js 框架之一,在 Hapi.js 中实现自定义异常处理也是一个比较常见的需求。本文将会介绍 Hapi.js 中实现自定义异常处理的技巧和优化方案。
Hapi.js 中的异常处理
在 Hapi.js 的请求处理链路中,如果出现了异常,Hapi.js 会通过回调函数的方式返回异常信息。以下是一个简单的示例代码:
-- -------------------- ---- ------- -------------- ------- ------ ----- --------- -------- ----- ----------------- -- - ----- --- ------------- - --- ---------------
运行上面的代码,访问 http://localhost:3000/users
将会抛出一个异常:
{"statusCode":500,"error":"Internal Server Error","message":"An internal server error occurred"}
可以看到,Hapi.js 默认将异常信息封装成了一个 JSON,返回给了客户端。但是在实际开发场景中,这样的异常信息并不能满足我们的需求。因此,我们需要进行自定义异常处理。
自定义异常处理
在 Hapi.js 中,实现自定义异常处理可以使用 onPreResponse
方法,该方法会在回包(response)被发送给客户端之前被调用。在该方法中,我们可以对异常信息进行处理,并返回给客户端自定义的异常信息。以下是一个简单的示例代码:
-- -------------------- ---- ------- --------------------------- ----------------- -- - ----- - -------- - - -------- -- ------------------ - ------ --------- - ----- - ------ - - --------- ----- - ----------- ------- - - ------- ----- ----- - - ----- ------------ -- ----------- -------- --------------- -- -------------- -- ------ ------------ ----- -------------------- --- -------------- ------- ------ ----- --------- -------- ----- ----------------- -- - ----- ----------------------- - ----- ----- --- - --- ---------------
在上面的代码中,我们通过 server.ext
方法注册了一个 onPreResponse
方法。在该方法中,我们首先判断响应是否为错误响应(使用 Boom.js 创建的响应对象都会被封装成错误响应),如果是则将其转换为自定义的异常返回。在上述示例中,我们通过 Boom.badRequest
创建了一个错误响应,其中指定了错误码({ code: 40001 }
),然后将该错误响应抛出。访问 http://localhost:3000/users
可以看到以下响应:
{ "error": { "code": 40001, "message": "参数错误" } }
上述代码中的 Boom
对象是 Hapi.js 内置的一个异常处理工具,可以通过其提供的方法创建各种类型的异常响应。
优化方案
在上面的示例代码中,我们只是简单地将 Hapi.js 默认错误响应进行了转换,但是实际情况可能并不是这样简单的。因此,我们需要考虑如何优化自定义异常处理的方案。
定义通用异常响应
在实际开发中,我们经常会遇到一些常见的异常类型,例如参数错误、权限不足、服务不可用等。为了方便统一处理这些异常类型,我们可以定义一个通用的异常响应,然后根据不同的异常类型进行赋值。以下是一个简单的示例代码:
-- -------------------- ---- ------- ----- --------- ------- ----- - ------------------- -------- ----- - --------------- ----------- - ------- --------- - ----- - - ----- --------------- ------- --------- - -------------------- ----- - ---------- -------- ------ - - -- -------- --------------------------- ----------------- -- - ----- - -------- - - -------- -- ------------------ - ------ --------- - ----- - ------ - - --------- ----- - ---- ------- - - ------- ----- ----- - - ----- ------------ -- --------------- -------- --------------- -- -------------- -- ------ ------------ ----- ------------------------ --- -------------- ------- ------ ----- --------- -------- ----- ----------------- -- - ----- --- ----------------------- --------- - --- ---------------
在上面的代码中,我们定义了一个 HttpError
类和 BadRequestError
类,前者是所有异常类型的基类,后者继承自 HttpError
,表示参数错误异常。在 onPreResponse
方法中,我们将响应异常转换为自定义异常类型,然后在返回时将响应转换为自定义异常响应。在路由中,我们将抛出一个 BadRequestError
类型的错误,其中指定了错误码('40001'
),然后将该错误响应抛出。
该方案的优点是能够提高代码的可读性和可维护性,同时也可以进行统一的异常处理。
使用插件进行异常处理
除了在代码中实现自定义异常处理外,Hapi.js 还提供了一种更加灵活的异常处理方式,即使用插件进行异常处理。该方式的优点是可以将异常处理逻辑独立出来,不与业务代码耦合,方便插件的可复用性。
以下是一个简单的插件实现示例:
-- -------------------- ---- ------- ----- --------- - ---------------------------- -------------- - - ----- ---------------- -------- -------- --------- ---------------- -------- - --------------------------- ----------------- -- - ----- - -------- - - -------- -- ------------------ - ------ --------- - ----- - ------ - - --------- ----- - ---- ------- - - ------- ----- ----- - - ----- ------------ -- --------------- -------- --------------- -- -------------- -- ------ ------------ ----- ------------------------ --- -- ----------- -------------------------- -------- -------------------- -------- ----- - ----- --- --------------------- -------- ------ --- -- --------------- -------------------------- ------------- ----------------- ----- - ----- --- -------------- -------- ------ --- - --
在上面的代码中,我们定义了一个 error-handler
插件,并在其中实现了自定义异常处理逻辑。在插件的 register
方法中,我们使用 server.ext
方法注册 onPreResponse
方法,然后在该方法中进行异常处理。在 toolkit
对象中,我们通过 server.decorate
方法定义了两个方法 throw
和 badRequest
,分别用于抛出通用异常类型和参数错误异常类型。这样,在业务代码中我们就可以方便地抛出异常了。
-- -------------------- ---- ------- ----------------- ------- ---------------------------------- --- -------------- ------- ------ ----- --------- -------- ----- ----------------- -- - -------------------- --------- - --- ---------------
在上述代码中,我们使用 server.register
方法注册了 error-handler
插件,然后在路由的业务处理代码中,通过调用 h.badRequest
方法抛出一个参数错误异常。
总结
本文介绍了 Hapi.js 中实现自定义异常处理的技巧和优化方案。通过自定义异常处理,我们可以对异常信息进行更细粒度的控制和优化,提高 API 服务的可读性和可维护性。在实际开发中,建议使用插件进行异常处理,方便进行异常处理逻辑的复用。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6531ca467d4982a6eb3b9a05