From d047c5d24e5d6d7b393ace678c3d8624392f28d1 Mon Sep 17 00:00:00 2001 From: Eric Kryski Date: Mon, 27 Feb 2017 15:29:56 -0700 Subject: [PATCH] adding better mongoose conflict error handling --- src/error-handler.js | 18 +++++++++++++++++- test/error-handler.test.js | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/error-handler.js b/src/error-handler.js index a90a9ed6..80c29d35 100644 --- a/src/error-handler.js +++ b/src/error-handler.js @@ -14,7 +14,23 @@ export default function errorHandler (error) { case 'DivergentArrayError': return Promise.reject(new errors.GeneralError(error)); case 'MongoError': - if (error.code === 11000) { + if (error.code === 11000 || error.code === 11001) { + // NOTE (EK): Error parsing as discussed in this github thread + // https://github.com/Automattic/mongoose/issues/2129 + const key = error.message.match(/_?([a-zA-Z]*)_?\d?\s*dup key/i)[1]; + let value = error.message.match(/\s*dup key:\s*\{\s*:\s*"?([a-zA-Z0-9'().]+)"?\s*\}/i)[1]; + + if (value === 'null') { + value = null; + } else if (value === 'undefined') { + value = undefined; + } + + error.message = `${key} '${value}' already exists.`; + error.errors = { + [key]: value + }; + return Promise.reject(new errors.Conflict(error)); } diff --git a/test/error-handler.test.js b/test/error-handler.test.js index 70b8bb8a..7b58ee83 100644 --- a/test/error-handler.test.js +++ b/test/error-handler.test.js @@ -113,13 +113,35 @@ describe('Feathers Mongoose Error Handler', () => { }).catch(done); }); - it('wraps a DuplicateKey error as a Conflict', done => { - let e = Error('Mock Duplicate Key Error'); - e.name = 'MongoError'; - e.code = 11000; - errorHandler(e).catch(error => { - expect(error).to.be.an.instanceof(errors.Conflict); - done(); - }).catch(done); + describe('DuplicateKey error', () => { + it('gets wrapped as a Conflict error', done => { + let e = Error('E11000 duplicate key error collection: db.users index: name_1 dup key: { : "Kate" }'); + e.name = 'MongoError'; + e.code = 11000; + errorHandler(e).catch(error => { + expect(error).to.be.an.instanceof(errors.Conflict); + done(); + }).catch(done); + }); + + it('has the correct error message', done => { + let e = Error("E11000 duplicate key error index: myDb.myCollection.$id dup key: { : ObjectId('57226808ec55240c00000272') }"); + e.name = 'MongoError'; + e.code = 11000; + errorHandler(e).catch(error => { + expect(error.message).to.equal(`id 'ObjectId('57226808ec55240c00000272')' already exists.`); + done(); + }).catch(done); + }); + + it('has the correct errors object', done => { + let e = Error('E11000 duplicate key error index: test.collection.$a.b_1 dup key: { : null }'); + e.name = 'MongoError'; + e.code = 11000; + errorHandler(e).catch(error => { + expect(error.errors).to.deep.equal({ b: null }); + done(); + }).catch(done); + }); }); });