balderdashy / sails

Realtime MVC Framework for Node.js
https://sailsjs.com
MIT License
22.82k stars 1.95k forks source link

MongoDB database error on duplicate returning unexpected result #4169

Closed cbarlow1993 closed 6 years ago

cbarlow1993 commented 7 years ago

Sails version: 1.0.0-36 Node version: v6.10.3 NPM version: 3.10.10 Operating system: Windows 10


As previously discussed on Gitter:

Sails hook: sails-hook-orm@2.0.0-21 Waterline: waterline@0.13.1-0 Sails-mongo: sails-mongo@1.0.0-9 Application running locally with sails lift. MongoDB deployed via Heroku on mongoLabs.

I'm getting a strange error returned from MongoDB which is not as expected.

I have overridden a Blueprint create model as below and on attempt to register a user in the database of which the email already exists, I expect a duplicate error that I can handle, alternatively I get the outputs below.

Contact me @cbarlow1993 on gitter if needed.

User.create(req.body)
      .meta({
        fetch: true
      })
      .exec(function (err, user) {

        console.log(err)
        // Return Error
        if (err) {
          if (err.code === 11000) {
            return res.status(409).send({
              "message": sails.config.errors.USER_ALREADY_EXISTS
            })
          }
          return res.status(400).send(err)
        }

        // Return User
        if (user) {
          return res.status(201).send({
            token: sails.helpers.createToken({
              user: user
            }).execSync(),
            user: user
          })
        }
      })

return res.send(500).json(err) will return :

{
    "name": "AdapterError",
    "adapterMethodName": "create",
    "modelIdentity": "user",
    "raw": {}
}

However, the console.log(err) returns:

{ AdapterError: Unexpected error from database adapter: { MongoError: E11000 duplicate key error index: heroku_jlfr908f.user.$email_1 dup key: { : "example@domain.com" }
    at Function.MongoError.create (D:\User\Documents\Development\project\node_modules\mongodb-core\lib\error.js:31:11)
    at toError (D:\User\Documents\Development\project\node_modules\mongodb\lib\utils.js:139:22)
    at D:\User\Documents\Development\project\node_modules\mongodb\lib\collection.js:739:67
    at D:\User\Documents\Development\project\node_modules\mongodb-core\lib\connection\pool.js:461:18
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickDomainCallback (internal/process/next_tick.js:128:9)
  name: 'MongoError',
  message: 'E11000 duplicate key error index: heroku_jlfr908f.user.$email_1 dup key: { : "example@domain.com" }',
  driver: true,
  index: 0,
  code: 11000,
  errmsg: 'E11000 duplicate key error index: heroku_jlfr908f.user.$email_1 dup key: { : "example@domain.com" }',
  footprint: { identity: 'notUnique', keys: [] } }
    at Object.create [as user/create] (D:\User\Documents\Development\project\api\controllers\UserController.js:19:10)
    at D:\User\Documents\Development\project\node_modules\sails\lib\router\bind.js:218:42
    at routeTargetFnWrapper (D:\User\Documents\Development\project\node_modules\sails\lib\router\bind.js:350:9)
    at Layer.handle [as handle_request] (D:\User\Documents\Development\project\node_modules\express\lib\router\layer.js:95:5)
    at next (D:\User\Documents\Development\project\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (D:\User\Documents\Development\project\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (D:\User\Documents\Development\project\node_modules\express\lib\router\layer.js:95:5)
    at D:\User\Documents\Development\project\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (D:\User\Documents\Development\project\node_modules\express\lib\router\index.js:335:12)
    at next (D:\User\Documents\Development\project\node_modules\express\lib\router\index.js:275:10)
    at next (D:\User\Documents\Development\project\node_modules\express\lib\router\route.js:127:14)
    at Hook.expressMiddleware (D:\User\Documents\Development\project\node_modules\sails\lib\hooks\i18n\index.js:191:14)
    at Hook.wrapper [as expressMiddleware] (D:\User\Documents\Development\project\node_modules\@sailshq\lodash\lib\index.js:3250:19)
    at addLocalizationMethod (D:\User\Documents\Development\project\node_modules\sails\lib\hooks\i18n\index.js:136:35)
    at routeTargetFnWrapper (D:\User\Documents\Development\project\node_modules\sails\lib\router\bind.js:350:9)
    at Layer.handle [as handle_request] (D:\User\Documents\Development\project\node_modules\express\lib\router\layer.js:95:5)
  name: 'AdapterError',
  adapterMethodName: 'create',
  modelIdentity: 'user',
  raw:
   Error: { MongoError: E11000 duplicate key error index: heroku_jlfr908f.user.$email_1 dup key: { : "example@domain.com" }
       at Function.MongoError.create (D:\User\Documents\Development\project\node_modules\mongodb-core\lib\error.js:31:11)
       at toError (D:\User\Documents\Development\project\node_modules\mongodb\lib\utils.js:139:22)
       at D:\User\Documents\Development\project\node_modules\mongodb\lib\collection.js:739:67
       at D:\User\Documents\Development\project\node_modules\mongodb-core\lib\connection\pool.js:461:18
       at _combinedTickCallback (internal/process/next_tick.js:73:7)
       at process._tickDomainCallback (internal/process/next_tick.js:128:9)
     name: 'MongoError',
     message: 'E11000 duplicate key error index: heroku_jlfr908f.user.$email_1 dup key: { : "example@domain.com" }',
     driver: true,
     index: 0,
     code: 11000,
     errmsg: 'E11000 duplicate key error index: heroku_jlfr908f.user.$email_1 dup key: { : "example@domain.com" }',
     footprint: { identity: 'notUnique', keys: [] } }
       at D:\User\Documents\Development\project\node_modules\sails-mongo\lib\private\do-with-connection.js:146:25
       at D:\User\Documents\Development\project\node_modules\sails-mongo\lib\private\do-with-connection.js:110:29
       at Object.handlers.notUnique (D:\User\Documents\Development\project\node_modules\sails-mongo\lib\private\build-std-adapter-method.js:66:56)
       at afterMaybeArtificiallyWaiting (D:\User\Documents\Development\project\node_modules\machine\lib\private\intercept-exit-callbacks.js:406:21)
       at maybeArtificiallyWait (D:\User\Documents\Development\project\node_modules\machine\lib\private\intercept-exit-callbacks.js:220:20)
       at afterPotentiallyCaching (D:\User\Documents\Development\project\node_modules\machine\lib\private\intercept-exit-callbacks.js:240:11)
       at _cacheIfAppropriate (D:\User\Documents\Development\project\node_modules\machine\lib\private\intercept-exit-callbacks.js:98:18)
       at Function._interceptExit [as notUnique] (D:\User\Documents\Development\project\node_modules\machine\lib\private\intercept-exit-callbacks.js:111:9)
       at D:\User\Documents\Development\project\node_modules\sails-mongo\lib\private\machines\create-record.js:83:24
       at D:\User\Documents\Development\project\node_modules\mongodb\lib\collection.js:431:32
       at handleCallback (D:\User\Documents\Development\project\node_modules\mongodb\lib\utils.js:120:56)
       at D:\User\Documents\Development\project\node_modules\mongodb\lib\collection.js:739:42
       at D:\User\Documents\Development\project\node_modules\mongodb-core\lib\connection\pool.js:461:18
       at _combinedTickCallback (internal/process/next_tick.js:73:7)
       at process._tickDomainCallback (internal/process/next_tick.js:128:9) }

User model is:

module.exports = {

  schema: true,

  attributes: {

    password: {
      type: 'string'
    },
    email: {
      type: 'string',
      isEmail: true,
      required: true,
      unique: true
    },
    firstName: {
      type: 'string'
    },
    lastName: {
      type: 'string'
    },
    facebookId: {
      type: 'string'
    }
  },

  customToJSON: function () {
    return _.omit(this, ['password'])
  },

  beforeUpdate: function (values, next) {

    console.log(values)
    if (values.password) {
      try {
        values.password = sails.helpers.hashPassword({
          password: values.password
        }).execSync();
        return next();
      } catch (err) {
        return next(err)
      }
    }
    return next()

  },
  beforeCreate: function (values, next) {
    if (values.password) {
      try {
        values.password = sails.helpers.hashPassword({
          password: values.password
        }).execSync();
        return next();
      } catch (err) {
        return next(err)
      }
    }
    return next()
  }

};
sailsbot commented 7 years ago

@cbarlow1993 Thanks for posting, we'll take a look as soon as possible.


For help with questions about Sails, click here. If you’re interested in hiring @sailsbot and her minions in Austin, click here.

Josebaseba commented 7 years ago

Same issue here. Everything goes as a string inside the message attribute:

// console.log(err.message)
// typeof err.message === string
Unexpected error from database adapter: { [MongoError: E11000 duplicate key error index: kuaderno.student.$username_1 dup key: { : "redbird" }]
  name: 'MongoError',
  message: 'E11000 duplicate key error index: kuaderno.student.$username_1 dup key: { : "redbird" }',
  driver: true,
  index: 0,
  code: 11000,
  errmsg: 'E11000 duplicate key error index: kuaderno.student.$username_1 dup key: { : "redbird" }',
  footprint: { identity: 'notUnique', keys: [] } }

// console.log(_.keys(err))
[ 'name', 'adapterMethodName', 'modelIdentity', 'raw' ]

// console.log(_.values(err))
[ 'AdapterError',
  'update',
  'student',
  [Error: { [MongoError: E11000 duplicate key error index: kuaderno.student.$username_1 dup key: { : "redbird" }]
    name: 'MongoError',
    message: 'E11000 duplicate key error index: kuaderno.student.$username_1 dup key: { : "redbird" }',
    driver: true,
    index: 0,
    code: 11000,
    errmsg: 'E11000 duplicate key error index: kuaderno.student.$username_1 dup key: { : "redbird" }',
    footprint: { identity: 'notUnique', keys: [] } }] ]
sailsbot commented 7 years ago

@cbarlow1993,@sailsbot,@Josebaseba: Hello, I'm a repo bot-- nice to meet you!

It has been 30 days since there have been any updates or new comments on this page. If this issue has been resolved, feel free to disregard the rest of this message and simply close the issue if possible. On the other hand, if you are still waiting on a patch, please post a comment to keep the thread alive (with any new information you can provide).

If no further activity occurs on this thread within the next 3 days, the issue will automatically be closed.

Thanks so much for your help!

Josebaseba commented 7 years ago

ping @sgress454

sgress454 commented 7 years ago

Looking at this now...

sgress454 commented 7 years ago

@cbarlow1993 @Josebaseba This should be patched on master of sails-mongo, if either of you would mind trying it out:

npm install github://balderdashy/sails-mongo
Josebaseba commented 6 years ago

Hi @sgress454 it's working 👍 Could you please publish the 1.0.0-10 version of the mongo adapter (with the AVG fix and this fix too)? Thanks

And, is there any place where we can see all the error codes? I had to find them in the waterline code but maybe I'm missing more. In the docs, we only have the E_UNIQUE code: http://next.sailsjs.com/documentation/concepts/models-and-orm/errors

Thanks!!

sgress454 commented 6 years ago

@Josebaseba re: 1.0.0-10, done!

Re: error codes, I think E_UNIQUE might be the only one right now. @mikermcneil?

mikermcneil commented 6 years ago

@Josebaseba @sgress454 should be in the v1 docs now, if memory serves. E_UNIQUE is the only .code which is relevant, for the most part-- though you'll also find usefulness in checking out .name (which describes the broader classification)

cbarlow1993 commented 6 years ago

Haven't had a chance to check the fix yet but I trust it works. Thanks @sgress454 & @mikermcneil for the fix.

Josebaseba commented 6 years ago

@cbarlow1993 it works! And @mikermcneil thanks for the info 👍

sailsbot commented 6 years ago

@cbarlow1993,@sailsbot,@Josebaseba,@sgress454,@mikermcneil: Hello, I'm a repo bot-- nice to meet you!

It has been 30 days since there have been any updates or new comments on this page. If this issue has been resolved, feel free to disregard the rest of this message and simply close the issue if possible. On the other hand, if you are still waiting on a patch, please post a comment to keep the thread alive (with any new information you can provide).

If no further activity occurs on this thread within the next 3 days, the issue will automatically be closed.

Thanks so much for your help!

mikermcneil commented 6 years ago

for future reference, docs about Waterline ORM errors now live at:

https://sailsjs.com/documentation/concepts/models-and-orm/errors

(^^ that link won't work for a few more days, but you can use the next. subdomain in the mean time)