后端开发笔记:eggjs 使用随笔
![Sam.C](/author/sam.c/avatar_hudd7b8f4f690d5cd6e80fa26326bc1e31_690768_50x50_fill_q85_h2_lanczos_center_3.webp)
今天遇到的奇怪的报错是路由定义好了,控制器和服务都写好了,就是一直报错启动不起来,报错是:
2024-05-12 08:09:36,597 ERROR 14124 [-/127.0.0.1/-/14ms GET /api/get-unitconversions] nodejs.TypeError: Cannot read properties of undefined (reading 'getUnitConversions')
at UnitConversionController.getUnitConversions (C:\work\mbos_saas\app\controller\unitconversion.js:62:63)
at Object.callFn (C:\work\mbos_saas\node_modules\egg-core\lib\utils\index.js:44:21)
at Object.classControllerMiddleware (C:\work\mbos_saas\node_modules\egg-core\lib\loader\mixin\controller.js:87:20)
at Object.callFn (C:\work\mbos_saas\node_modules\@eggjs\router\lib\utils.js:12:21)
at wrappedController (C:\work\mbos_saas\node_modules\@eggjs\router\lib\egg_router.js:322:18)
at dispatch (C:\work\mbos_saas\node_modules\@eggjs\router\node_modules\koa-compose\index.js:44:32)
at next (C:\work\mbos_saas\node_modules\@eggjs\router\node_modules\koa-compose\index.js:45:18)
at C:\work\mbos_saas\node_modules\@eggjs\router\lib\router.js:186:18
at dispatch (C:\work\mbos_saas\node_modules\@eggjs\router\node_modules\koa-compose\index.js:44:32)
at C:\work\mbos_saas\node_modules\@eggjs\router\node_modules\koa-compose\index.js:36:12
headers: {"Access-Control-Allow-Origin":"http://localhost:8000","Access-Control-Allow-Credentials":"true","vary":"Origin"}
pid: 14124
hostname: DESKTOP-MF9BLRQ
一直说找不到这个方法。但是明明控制器和服务中都定义了的。
最后把路由器中的 this.service.unitConversion.getUnitConversions
中的服务名改成小写而解决 unitconversion
。一个字母大小写引发的惨案。
编写规范
- 错误传递非常重要:
eggjs
已经内置了统一的错误处理模块,几乎不用特别的处理,在写service
时,使用try catch
块把prisma
的操作包裹起来是很有必要的,在catch
块中,可以return
一个对象,有一个message
属性,属性的值根据使用的数据库操作方式而不同,如果使用prisma
,那可以是:
try{
}
catch(error){
return {
message: error.meta
}
}
catch
中 return
的对象会被传递给控制器,写入 ctx.body
中。而 meta
是 prisma
内部错误处理机制的核心成员,包括和出错的模块和原因。
最好不要把
ctx
直接传递给service
,controller
用于接收、解构request
对象的值并进行验证(可以使用Joi
验证库,非常好用)和封装response
对象,结构出的值经过验证以后,传递给service
,使之专注于数据库操作和核心业务逻辑的实现,和controller
各司其职。在
controller
中,可以直接使用this.service
直接获取到当前请求上下文的Service
对象,可以直接调用service
中定义的方法。而在service
中,就需要通过构造函数显示引入的方式,才能访问app
启动时挂载的服务:
class UnitService extends Service {
constructor(props) {
super(props)
this.prisma = this.ctx.app.prisma;
this.casdoor = this.ctx.app.casdoor;
}
async getUnit(id) {
}
}
以上定义的错误返回方式,一般可以很好的反应导致错误的原因,但是有时候也会有例外。
路由路径可以有多种组装方式,
router.put('unit', '/api/update-unit/:ownerId/:id', controller.unit.updateUnit);
这种方式可以通过this.ctx.params
获取到路由路径中的ownerId
和id
,其他内容还是通过this.ctx.request.body
和this.ctx.query
(查询参数)获取。