概述
最近做了一个类似于论坛的项目,主要就是nodejs和mysql的使用。记录一下项目中遇到的问题和思路,这篇文章专门讲遇到的error、错误以及解决措施
-
SyntaxError: await is only valid in async function
场景是这样的:(具体逻辑就不写了,太多了写出来很乱,反而找不到重点)
const verifyUser=(*ctx*,*next*)*=>*{ //拿到用户名和密码 //判断用户名和密码不为空 //判断注册的用户名是否被注册过 await next() } const handlePassword=async(ctx,next)=>{ const {password} = ctx.request.body ctx.request.body.password = md5password(password) await next() } //调用顺序是这样的 userRouter.post('/',verifyUser,handlePassword,create)
解决:因为next()表示进行下一个中间件的处理,所以我一直在找下面的逻辑,没有看它本身,把verifyUser加上了个async修饰就好了。
const verifyUser=async(*ctx*,*next*)*=>*{}
-
Error: Cannot find module 'auth_router.js'
Require stack:
E:VSCode Workcoderhubsrcrouterindex.js
E:VSCode Workcoderhubsrcappindex.js
E:VSCode Workcoderhubsrcindex.js
看这里报错,他说找不到auth_router.js这个模块。但是我自己知道没问题,那就说明问题出在找的过程中了,然后看了看,改成相对路径require(
./${*file*}
)。前面忘记写./了const useRoutes = (*app*)*=>*{ fs.readdirSync(__dirname).forEach(*file**=>*{ if(*file* === 'index.js') return ; *const* router = require(`./${*file*}`) *app*.use(router.routes()) *app*.use(router.allowedMethods()) }) }
-
server at http://127.0.0.1:8000
E:VSCode Workcoderhubsrcappdatabse.js:14
conn.connect(err=>{
^
TypeError: Cannot read property 'connect' of undefined at E:VSCode Workcoderhubsrcappdatabse.js:14:8 at E:VSCode Workcoderhubnode_modulesmysql2libpool.js:60:18
这个报错非常的明显,我们的服务器运行成功了, 但是,在数据库的连接时候出了问题。他说connect是undefined,为什么不存在呢,肯定是因为没连接上,重启了一下数据库,就是那个运行程序的小图标,重启完就好了。
-
(node:6620) Warning: Accessing non-existent property 'create' of module exports inside circular dependency (Use node --trace-warnings ... to show where the warning was created)
打印这里是因为我使用postman调试的时候,打印的错误信息一直有问题,比如设置了用户名或密码不为空,但是只提示not found于是我去找问题,打印一下这里,打印一下那里。try catch一下,提示了这个警告。大意是(节点:6620)警告:在循环依赖关系中访问不存在的模块导出属性“create”。但是我确实没找到到底在哪,而且只是警告,所以不管他了
发现都没有错,控制台报出来的也是
Error: name_or_password_can_not_be_empty
最后我只好去找了错误处理的函数发现符号打错了!!
switch (*error*.message){
我把.打成了, 让人伤心欲绝!!改完了立马正常了 -
关于发生了重名问题而没有错误提示仍然直接插入数据库的问题:
看了一下每个地方的逻辑都没有问题:
-
打印getUserByName这个函数得到的结果,发现就是数据库里面的用户列表
-
打印调用它的位置得到的结果,发现是个
Promise { <pending> }
,怪不得没判断出来,一直添加。这个错误也很明显 ,就是和promise相关,检查发现我声明函数写的async,而这里调用却没加await,那么就很容易了*
const* result = await service.getUserByName(name)
-
-
在进行登陆验证的时候,无法登陆成功,如果是密码错误会有相应提示,但是发送正确的,就会一直显示
Internal Server Error
,服务器错误。说明verifyLogin函数是完全能运行的,在函数结束的地方输出结果也是一样能输出的,所以错误应该在await next()处。try catch一下,报这个错误:ReferenceError: next is not defined
at verifyLogin (E:VSCode Workcoderhubsrcmiddlewareauth_middleware.js:33:5)然后仔细检查函数发现两个参数context和next,写错了写成了,ctx和err,所以一直进不去下一个函数。虽然感觉又是一个非常低级的错误,但是这个也培养了我找bug的思路
-
发布动态的时候也一直显示服务器错误,要注意看,我是因为没有携带token,所以一直失败
-
Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server versionfor the right syntax to use near 'FROM moment m LEFT JOIN user u ON m.user_id = u.id LIMIT ?,?' at line 4
这个错误非常的简单,因为我是写了完整的然后来记录一下错误,所以说,中间删去了一些语句,所以
JSON_OBJECT('id',u.id,'name',u.name) user
后面的,逗号没删,这就导致了select from 中间有个逗号,所以说报错了 -
E:VSCode Workcoderhubnode_moduleskoa-routerliblayer.js:37
throw new Error(
^
Error: get /test: middleware must be a function, not undefined
这是我在优化验证身份的函数时候报的错误,说中间件必须是个函数,而不是undefined
/test的逻辑
authRouter.get('/test', verifyAuth,verifyPermission("user"),success)
去掉verifyPermission这个函数是可以正常运行的,所以说问题就出在这里。
闭包里要写return作为返回值,我这里是返回一个函数,加上了return就好了
-
还有一个问题就是我在对评论进行回复的时候,postman一直提示NOT FOUND,四处找问题,打印,发现都没错。后面我想试试是不是sql语句有问题,就在数据库里写了一下,然后获取数据发现刚才的都生效了,但是一直提示not found。我又去控制台打印,发现结果获取是正确的,就是忘了返回到context上显示:
*ctx*.body = result
。所以说要注意提示代码的编写
-
E:VSCode Workcoderhubnode_modulesmysql2libpool.js:177
throw e;
^
TypeError: Bind parameters must not contain undefined. To pass SQL NULL specify JS null
这是在进行修改评论时候出现的问题,感觉这个不是很容易找,于是我从删除评论部分去试了试,发现是一样的错误(因为二者的逻辑很相似)
//修改评论 commentRouter.patch('/:commentId',verifyAuth,verifyPermission("comment"),update) //删除评论 commentRouter.delete('/:commentId',verifyAuth,verifyPermission("comment"),remove)
于是先删掉了verifyPermission这个逻辑,发现能正常运行了,加上这个就报错。首先我发现这个中间件的验证逻辑是获取params里携带的momentId,而我上面写的是commentId,所以是获取不到momentId的。这时候打印momentId得到的是undefined。如果把参数加在params里是这样:
{ commentId: 'momentId=8' } 1
后面的1是用户id。直接传要修改的评论的id,是这样的结果:
{ commentId: '8' } 1
,这样取出来的是一个对象,而我需要的只是一个int类型的数据。const verifyPermission=(tableName)=>{ return async (ctx,next)=>{ console.log(tableName) const {momentId} = ctx.params const {id} = ctx.user console.log(ctx.params,id) try{ const isPerission = await AuthService.checkResource(tableName,momentId,id) if(!isPerission) throw new Error() await next() }catch(err){ const error = new Error(errorType.UNPERMISSION) return ctx.app.emit('error',error,ctx) } } }
所以想到了对象[字符串]取属性的方法,于是不用解构赋值的方法取momentId,就让他等于这个对象,然后这个tableName是随着传入的数据表名称变化的,刚好id也是跟这个一样,所以用模板字符串拼接作为属性字符串,就可以取出来了。传给下一个函数,运行正常!
const momentId = ctx.params const {id} = ctx.user const index = `${tableName}Id` console.log(ctx.params.momentId,momentId[index],id)
修改完成后,删除评论和修改评论都可以正常运行了
(我这个软件不知道怎么了,英文字体看起来像是被修改了,而且还只有关键字这样,我不会改,将就看吧)
-
Error: Duplicate entry '5' for key 'moment_label.PRIMARY'
这个错误说是重复条目,给的提示是没有操作权限。我打印很多地方都不知道问题到底出在哪,然后百度看到了两个解决方案:
原因一:
对应表名称主键没有设置自增
解决方法:设置主键自增原因二:
插入线程频率较高,没有处理好事务,造成插入sql执行顺序混乱
解决方法:把insert into 表名()values();修改为:insert ignore into 表名()values();我看了我的操作所设计的数据表,发现都设置了自增,于是用第二种方法,加一个ignore ,成功解决。原理是这样的,https://blog.51cto.com/u_15305798/3157131,这是原博
原因:这是由于表中对应字段设置了唯一索引,在我们进行逻辑删除时,并没有真正的删除,只是标记为删除状态而已,
当我们再进行新增的时候,由于有唯一索引的限制,导致我们不能进行新增成功,所以报错.
解决方法1:
如果允许的话,把数据库中该字段的唯一索引限制去掉,这样后端可以进行逻辑删除,新增时即使与标记为删除的记录的字段值相等,由于没有唯一索引的限制,可以正常新增
解决方法2:不需要去掉数据库中的唯一索引限制,但是当后端开发进行删除操作的时候,执行的是物理删除的sql语句(真正的删除),而不是逻辑删除,同时后端用逻辑判断,去查询数据库中是否有相同的编号存在,如果存在,则不允许新增,如果不存在,则可以新增
-
Error: Unexpected field
最后一次错误,这是在用postman测试上传文件时候报的错误提示,我不知道为什么会这样,去网上搜了一下,搜到的办法我都试过了,但是没有用。后面会持续留意的,等解决了再补充上来。
最后
以上就是爱撒娇背包为你收集整理的nodejs案例coderhub在实现过程中的error的全部内容,希望文章能够帮你解决nodejs案例coderhub在实现过程中的error所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复