首页 > 解决方案 > 我有 TypeError [ERR_INVALID_CALLBACK]: Callback must be a function

问题描述

我使用 express-formidable 来处理表单的上传。表单的普通字段安装到req.fields.

表单上传的文件挂载到req.files,文件存放在public/img目录中。然后验证参数。

验证通过后,将用户信息插入MongoDB。如果成功,会跳转到首页并显示“注册成功”的通知。如果失败(如果用户名被占用),会跳转回注册页面,并显示“用户名已被占用”通知。

TypeError [ERR_INVALID_CALLBACK]:回调必须是函数

const fs = require('fs')
const path = require('path')
const sha1 = require('sha1')
const express = require('express')
const router = express.Router()

const UserModel = require('../models/users')
const checkNotLogin = require('../middlewares/check').checkNotLogin

//Get /register The Page to Create account
router.get('/', checkNotLogin, function (req, res, next){
    res.render('register')
})

router.post('/', checkNotLogin, function(req, res, next){
     const name = req.fields.name
     const gender = req.fields.gender
     const emailaddress = req.fields.emailaddress
     const bio = req.fields.bio
     const avatar = req.files.avatar.path.split(path.sep).pop()
     let password = req.fields.password
     const repassword = req.fields.repassword

     try {
         if (!(name.length >= 1 && name.length <= 10)) {
           throw new Error('Username can not be longer than 10 characters')
         }
         if (['m', 'f', 'x'].indexOf(gender) === -1) {
           throw new Error('Gender only can be m、f or x')
         }
         if(!emailaddress.endsWith('.co.uk')){
             throw new Error('Email Address should be an academic address')
         }
         if (!(bio.length >= 1 && bio.length <= 30)) {
           throw new Error('Please organise your personal description with in 30 characters')
         }
         if (!req.files.avatar.name) {
           throw new Error('Please choose your avator')
         }
         if (password.length < 6) {
           throw new Error('Password should be longer than 6 characters')
         }
         if (password !== repassword) {
           throw new Error('Re-enter the password you set')
         }
       } catch (e) {
         // register fail, delete the avator
         fs.unlink(req.files.avatar.path)
         req.flash('error', e.message)
         return res.redirect('/register')
       }

       // text password encryption
       password = sha1(password)

       // information wait to be enter into database
       let user = {
         name: name,
         password: password,
         emailaddress:emailaddress,
         gender: gender,
         bio: bio,
         avatar: avatar
       }
       // enter user information into database
       UserModel.create(user)
         .then( function (result) {
           user = result.ops[0]
           // delete password,store user information into session
           delete user.password
           req.session.user = user
           //Write into flash
            req.flash('success', 'Account Successfully created')
           // Jump to the home
           res.redirect('/posts')
          })
         .catch(function (e) {
           // Account create failure, delete avator
            fs.unlink(req.files.avatar.path)
           // if username already been use return to register page
           if (e.message.match('duplicate key')) {
             req.flash('error', 'username already be taken')
             return res.redirect('/register')
           }
          next(e)
         })
      })

     module.exports = router

我不确定哪里出了问题我认为已经有功能任何帮助将不胜感激

这是完整的错误消息:

 TypeError [ERR_INVALID_CALLBACK]: Callback must be a function
 at makeCallback (fs.js:137:11)
 at Object.unlink (fs.js:936:14)
 at D:\tttt\CVsWeb\routes\register.js:48:1 express\lib\router\layer.js:95:5)
 at Layer.handle [as handle_request] (D:\tttt\CVsWeb\node_modules\137:13 express\lib\router\layer.js:95:5)
 at next        (D:\tttt\CVsWeb\node_modules\express\lib\router\route.js:express\lib\router\layer.js:95:5)137:13)                                                              137:13)
 at checkNotLogin (D:\tttt\CVsWeb\middlewares\check.js:14:9)      \route.js:112:3)
 at Layer.handle [as handle_request(D:\tttt\CVsWeb\node_modules\express\lib\router\layer.js:95:5)express\lib\router\layer.js:95:5)
at next (D:\tttt\CVsWeb\node_modules\express\lib\router\route.js:137:13)
at Route.dispatch (D:\tttt\CVsWeb\node_modules\express\lib\router\route.js:112:3)
  at Layer.handle [as handle_request] (D:\tttt\CVsWeb\node_modules\express\lib\router\layer.js:95:5)

标签: node.js

解决方案


fs.unlink是异步的,需要一个回调函数作为它的第二个参数传递。

尝试使用fs.unlinkSync(req.files.avatar.path)或插入一个函数作为您的第二个参数unlink fs.unlink(req.files.avatar.path, function(){console.log('Deleted avatar')})

router.post('/', checkNotLogin, function(req, res, next) {
  const name = req.fields.name
  const gender = req.fields.gender
  const emailaddress = req.fields.emailaddress
  const bio = req.fields.bio
  const avatar = req.files.avatar.path.split(path.sep).pop()
  let password = req.fields.password
  const repassword = req.fields.repassword

  try {
    if (!(name.length >= 1 && name.length <= 10)) {
      throw new Error('Username can not be longer than 10 characters')
    }
    if (['m', 'f', 'x'].indexOf(gender) === -1) {
      throw new Error('Gender only can be m、f or x')
    }
    if (!emailaddress.endsWith('.co.uk')) {
      throw new Error('Email Address should be an academic address')
    }
    if (!(bio.length >= 1 && bio.length <= 30)) {
      throw new Error('Please organise your personal description with in 30 characters')
    }
    if (!req.files.avatar.name) {
      throw new Error('Please choose your avator')
    }
    if (password.length < 6) {
      throw new Error('Password should be longer than 6 characters')
    }
    if (password !== repassword) {
      throw new Error('Re-enter the password you set')
    }
  } catch (e) {
    // register fail, delete the avator
    fs.unlinkSync(req.files.avatar.path) //Try this!
    req.flash('error', e.message)
    return res.redirect('/register')
  }

  // text password encryption
  password = sha1(password)

  // information wait to be enter into database
  let user = {
    name: name,
    password: password,
    emailaddress: emailaddress,
    gender: gender,
    bio: bio,
    avatar: avatar
  }
  // enter user information into database
  UserModel.create(user)
    .then(function(result) {
      user = result.ops[0]
      // delete password,store user information into session
      delete user.password
      req.session.user = user
      //Write into flash
      req.flash('success', 'Account Successfully created')
      // Jump to the home
      res.redirect('/posts')
    })
    .catch(function(e) {
      // Account create failure, delete avator
      fs.unlinkSync(req.files.avatar.path) //Also this one
      // if username already been use return to register page
      if (e.message.match('duplicate key')) {
        req.flash('error', 'username already be taken')
        return res.redirect('/register')
      }
      next(e)
    })
})

推荐阅读