From e20f9abe35f38320176e040553555f21ea9ea3c3 Mon Sep 17 00:00:00 2001 From: "Andrew E. Rhyne" Date: Tue, 14 Mar 2017 12:22:39 -0700 Subject: [PATCH] rely on error.originalError and fail back to error for formatError --- CHANGELOG.md | 14 +++--- dist/index.js | 118 ++++++++++++++++++++-------------------------- dist/index.js.map | 2 +- package.json | 2 +- src/index.js | 86 ++++++++++++++------------------- test/spec.js | 6 +-- 6 files changed, 99 insertions(+), 129 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f909826..5c91171 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,25 +1,25 @@ 1.3.0 / 2017-02-01 ================== - * Update README.md - * Add Beerpay's badge - * Added isInstance method + * Docs: Update README.md (@thebigredgeek) + * Docs: Add Beerpay's badge (@thebigredgeek) + * Docs: Added isInstance method 1.2.1 / 2016-12-07 ================== - * Fixed a bug with overriding message serialization + * Fix: bug with overriding message serialization (@thebigredgeek) 1.2.0 / 2016-12-07 ================== - * Added option to override message when throwing error (@thebigredgeek) + * Feature: Added option to override message when throwing error (@thebigredgeek) 1.1.0 / 2016-12-01 ================== - * Added option to show original locations and paths in error (#1, @scf4) + * Feature: Added option to show original locations and paths in error (#1, @scf4) 1.0.2 / 2016-11-11 ================== - * Fix for data serialization (@thebigredgeek) + * Fix: data serialization (@thebigredgeek) 1.0.1 / 2016-11-10 ================== diff --git a/dist/index.js b/dist/index.js index db87256..370257f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -3,9 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); -exports.isInstance = exports.formatError = exports.createError = undefined; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); +exports.formatError = exports.createError = exports.isInstance = undefined; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); @@ -21,21 +19,6 @@ function _possibleConstructorReturn(self, call) { if (!self) { throw new Referen function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } -var errorMap = new Map(); - -var DELIMITER = '/::/'; - -var serializeName = function serializeName() { - var arr = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; - return arr.reduce(function (str, val) { - return '' + (str.length > 0 ? str + DELIMITER : str) + (val.toString ? val.toString() : val); - }, ''); -}; -var deserializeName = function deserializeName() { - var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; - return name.split(DELIMITER); -}; - var ApolloError = function (_ExtendableError) { _inherits(ApolloError, _ExtendableError); @@ -50,43 +33,45 @@ var ApolloError = function (_ExtendableError) { _classCallCheck(this, ApolloError); - var t = arguments[2] && arguments[2].thrown_at || time_thrown; + var t = arguments[2] && arguments[2].time_thrown || time_thrown; var d = Object.assign({}, data, arguments[2] && arguments[2].data || {}); var m = arguments[2] && arguments[2].message || message; var opts = Object.assign({}, options, arguments[2] && arguments[2].options || {}); - var _this = _possibleConstructorReturn(this, (ApolloError.__proto__ || Object.getPrototypeOf(ApolloError)).call(this, serializeName([name, t, m !== message ? m : 'null', Object.assign({}, d, { - toString: function toString() { - return JSON.stringify(d); - } - })]))); - - _this._name = name; - _this._humanized_message = m || ''; - _this._time_thrown = t; - _this._data = d; - _this._locations = opts.showLocations && arguments[2] && arguments[2].locations; - _this._path = opts.showPath && arguments[2] && arguments[2].path; + var _this = _possibleConstructorReturn(this, (ApolloError.__proto__ || Object.getPrototypeOf(ApolloError)).call(this, m)); + + _this.name = name; + _this.message = m; + _this.time_thrown = t; + _this.data = d; + _this._showLocations = !!opts.showLocations; return _this; } _createClass(ApolloError, [{ key: 'serialize', value: function serialize() { - var name = this._name; - var message = this._humanized_message; - var time_thrown = this._time_thrown; - var data = this._data; - var locations = this._locations; - var path = this._path; + var name = this.name, + message = this.message, + time_thrown = this.time_thrown, + data = this.data, + _showLocations = this._showLocations, + path = this.path, + locations = this.locations; + + var error = { message: message, name: name, time_thrown: time_thrown, data: data }; - if (locations) error.locations = locations; - if (path) error.path = path; + + if (_showLocations) { + error.locations = locations; + error.path = path; + } + return error; } }]); @@ -94,42 +79,43 @@ var ApolloError = function (_ExtendableError) { return ApolloError; }(_es6Error2.default); +var isInstance = exports.isInstance = function isInstance(e) { + return e instanceof ApolloError; +}; + var createError = exports.createError = function createError(name) { var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { message: 'An error has occurred', options: options }; var e = ApolloError.bind(null, name, data); - errorMap.set(name, e); return e; }; -var formatError = exports.formatError = function formatError(originalError) { +var formatError = exports.formatError = function formatError(error) { var returnNull = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - var _deserializeName = deserializeName(originalError.message), - _deserializeName2 = _slicedToArray(_deserializeName, 4), - name = _deserializeName2[0], - thrown_at = _deserializeName2[1], - m = _deserializeName2[2], - d = _deserializeName2[3]; - - var locations = originalError.locations, - path = originalError.path; - - var data = d !== undefined ? JSON.parse(d) : {}; - if (!name) return returnNull ? null : originalError; - var CustomError = errorMap.get(name); - if (!CustomError) return returnNull ? null : originalError; - var error = new CustomError({ - message: m === 'null' ? undefined : m, - thrown_at: thrown_at, - data: data, - locations: locations, - path: path - }); - return error.serialize(); -}; + var originalError = error ? error.originalError || error : null; -var isInstance = exports.isInstance = function isInstance(e) { - return e instanceof ApolloError; + if (!originalError) return returnNull ? null : error; + + var name = originalError.name; + + + if (!name || !isInstance(originalError)) return returnNull ? null : error; + + var time_thrown = originalError.time_thrown, + message = originalError.message, + data = originalError.data, + _showLocations = originalError._showLocations; + + + if (_showLocations) { + var locations = error.locations, + path = error.path; + + originalError.locations = locations; + originalError.path = path; + } + + return originalError.serialize(); }; //# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/dist/index.js.map b/dist/index.js.map index da250f8..41d3c97 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["../src/index.js"],"names":["errorMap","Map","DELIMITER","serializeName","arr","reduce","str","val","length","toString","deserializeName","name","split","ApolloError","message","time_thrown","Date","toISOString","data","options","t","arguments","thrown_at","d","Object","assign","m","opts","JSON","stringify","_name","_humanized_message","_time_thrown","_data","_locations","showLocations","locations","_path","showPath","path","error","createError","e","bind","set","formatError","originalError","returnNull","undefined","parse","CustomError","get","serialize","isInstance"],"mappings":"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","file":"index.js","sourcesContent":["import ExtendableError from 'es6-error';\n\nconst errorMap = new Map();\n\nconst DELIMITER = '/::/';\n\nconst serializeName = (arr = []) => arr\n .reduce((str, val) => (\n `${str.length > 0 ? str + DELIMITER : str}${val.toString ? val.toString() : val}`\n ), '');\nconst deserializeName = (name = '') => name.split(DELIMITER);\n\nclass ApolloError extends ExtendableError {\n constructor (name, {\n message,\n time_thrown = (new Date()).toISOString(),\n data = {},\n options = {},\n }) {\n const t = (arguments[2] && arguments[2].thrown_at) || time_thrown;\n const d = Object.assign({}, data, ((arguments[2] && arguments[2].data) || {}));\n const m = (arguments[2] && arguments[2].message) || message;\n const opts = Object.assign({}, options, ((arguments[2] && arguments[2].options) || {}));\n\n super(serializeName([\n name,\n t,\n (m !== message ? m : 'null'),\n Object.assign({}, d, {\n toString: () => JSON.stringify(d)\n }),\n ]));\n\n this._name = name;\n this._humanized_message = m || '';\n this._time_thrown = t;\n this._data = d;\n this._locations = (opts.showLocations && arguments[2] && arguments[2].locations)\n this._path = (opts.showPath && arguments[2] && arguments[2].path);\n }\n serialize () {\n const name = this._name;\n const message = this._humanized_message;\n const time_thrown = this._time_thrown;\n const data = this._data;\n const locations = this._locations;\n const path = this._path;\n let error = {\n message,\n name,\n time_thrown,\n data,\n };\n if (locations) error.locations = locations;\n if (path) error.path = path;\n return error;\n }\n}\n\nexport const createError = (name, data = { message: 'An error has occurred', options }) => {\n const e = ApolloError.bind(null, name, data);\n errorMap.set(name, e);\n return e;\n};\n\nexport const formatError = (originalError, returnNull = false) => {\n const [ name, thrown_at, m, d ] = deserializeName(originalError.message);\n const { locations, path } = originalError;\n const data = d !== undefined ? JSON.parse(d) : {};\n if (!name) return returnNull ? null : originalError;\n const CustomError = errorMap.get(name);\n if (!CustomError) return returnNull ? null : originalError;\n const error = new CustomError({\n message: m === 'null' ? undefined : m,\n thrown_at,\n data,\n locations,\n path,\n });\n return error.serialize();\n};\n\nexport const isInstance = e => e instanceof ApolloError;\n"]} \ No newline at end of file +{"version":3,"sources":["../src/index.js"],"names":["ApolloError","name","message","time_thrown","Date","toISOString","data","options","t","arguments","d","Object","assign","m","opts","_showLocations","showLocations","path","locations","error","isInstance","e","createError","bind","formatError","returnNull","originalError","serialize"],"mappings":"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","file":"index.js","sourcesContent":["import ExtendableError from 'es6-error';\n\nclass ApolloError extends ExtendableError {\n constructor (name, {\n message,\n time_thrown = (new Date()).toISOString(),\n data = {},\n options = {},\n }) {\n const t = (arguments[2] && arguments[2].time_thrown) || time_thrown;\n const d = Object.assign({}, data, ((arguments[2] && arguments[2].data) || {}));\n const m = (arguments[2] && arguments[2].message) || message;\n const opts = Object.assign({}, options, ((arguments[2] && arguments[2].options) || {}));\n\n super(m);\n\n this.name = name;\n this.message = m;\n this.time_thrown = t;\n this.data = d;\n this._showLocations = !!opts.showLocations;\n }\n serialize () {\n const { name, message, time_thrown, data, _showLocations, path, locations } = this;\n\n let error = {\n message,\n name,\n time_thrown,\n data,\n };\n\n if (_showLocations) {\n error.locations = locations;\n error.path = path;\n }\n\n return error;\n }\n}\n\nexport const isInstance = e => e instanceof ApolloError;\n\nexport const createError = (name, data = { message: 'An error has occurred', options }) => {\n const e = ApolloError.bind(null, name, data);\n return e;\n};\n\nexport const formatError = (error, returnNull = false) => {\n const originalError = error ? error.originalError || error : null;\n\n if (!originalError) return returnNull ? null : error;\n\n const { name } = originalError;\n\n if (!name || !isInstance(originalError)) return returnNull ? null : error;\n\n const { time_thrown, message, data, _showLocations } = originalError;\n\n if (_showLocations) {\n const { locations, path } = error;\n originalError.locations = locations;\n originalError.path = path;\n }\n\n return originalError.serialize();\n};\n"]} \ No newline at end of file diff --git a/package.json b/package.json index 3571ab5..34e5f06 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "apollo-errors", - "version": "1.3.0", + "version": "1.4.0", "description": "Machine-readable custom errors for Apollostack's GraphQL server", "main": "dist/index.js", "scripts": { diff --git a/src/index.js b/src/index.js index 0733aaa..f97c9c7 100644 --- a/src/index.js +++ b/src/index.js @@ -1,15 +1,5 @@ import ExtendableError from 'es6-error'; -const errorMap = new Map(); - -const DELIMITER = '/::/'; - -const serializeName = (arr = []) => arr - .reduce((str, val) => ( - `${str.length > 0 ? str + DELIMITER : str}${val.toString ? val.toString() : val}` - ), ''); -const deserializeName = (name = '') => name.split(DELIMITER); - class ApolloError extends ExtendableError { constructor (name, { message, @@ -17,67 +7,61 @@ class ApolloError extends ExtendableError { data = {}, options = {}, }) { - const t = (arguments[2] && arguments[2].thrown_at) || time_thrown; + const t = (arguments[2] && arguments[2].time_thrown) || time_thrown; const d = Object.assign({}, data, ((arguments[2] && arguments[2].data) || {})); const m = (arguments[2] && arguments[2].message) || message; const opts = Object.assign({}, options, ((arguments[2] && arguments[2].options) || {})); - super(serializeName([ - name, - t, - (m !== message ? m : 'null'), - Object.assign({}, d, { - toString: () => JSON.stringify(d) - }), - ])); + super(m); - this._name = name; - this._humanized_message = m || ''; - this._time_thrown = t; - this._data = d; - this._locations = (opts.showLocations && arguments[2] && arguments[2].locations) - this._path = (opts.showPath && arguments[2] && arguments[2].path); + this.name = name; + this.message = m; + this.time_thrown = t; + this.data = d; + this._showLocations = !!opts.showLocations; } serialize () { - const name = this._name; - const message = this._humanized_message; - const time_thrown = this._time_thrown; - const data = this._data; - const locations = this._locations; - const path = this._path; + const { name, message, time_thrown, data, _showLocations, path, locations } = this; + let error = { message, name, time_thrown, data, }; - if (locations) error.locations = locations; - if (path) error.path = path; + + if (_showLocations) { + error.locations = locations; + error.path = path; + } + return error; } } +export const isInstance = e => e instanceof ApolloError; + export const createError = (name, data = { message: 'An error has occurred', options }) => { const e = ApolloError.bind(null, name, data); - errorMap.set(name, e); return e; }; -export const formatError = (originalError, returnNull = false) => { - const [ name, thrown_at, m, d ] = deserializeName(originalError.message); - const { locations, path } = originalError; - const data = d !== undefined ? JSON.parse(d) : {}; - if (!name) return returnNull ? null : originalError; - const CustomError = errorMap.get(name); - if (!CustomError) return returnNull ? null : originalError; - const error = new CustomError({ - message: m === 'null' ? undefined : m, - thrown_at, - data, - locations, - path, - }); - return error.serialize(); -}; +export const formatError = (error, returnNull = false) => { + const originalError = error ? error.originalError || error : null; -export const isInstance = e => e instanceof ApolloError; + if (!originalError) return returnNull ? null : error; + + const { name } = originalError; + + if (!name || !isInstance(originalError)) return returnNull ? null : error; + + const { time_thrown, message, data, _showLocations } = originalError; + + if (_showLocations) { + const { locations, path } = error; + originalError.locations = locations; + originalError.path = path; + } + + return originalError.serialize(); +}; diff --git a/test/spec.js b/test/spec.js index daeeee0..fc510b4 100644 --- a/test/spec.js +++ b/test/spec.js @@ -32,7 +32,7 @@ describe('createError', () => { expect(message).to.equal('A foo 2.0 error has occurred'); expect(name).to.equal('FooError'); - expect(time_thrown).to.equal(e._time_thrown); + expect(time_thrown).to.equal(e.time_thrown); expect(data).to.eql({ hello: 'world', foo: 'bar' @@ -62,7 +62,7 @@ describe('formatError', () => { }); const s = formatError({ - message: e.message + originalError: e }, false); expect(s).to.eql(e.serialize()); @@ -85,7 +85,7 @@ describe('formatError', () => { const e = new FooError(); const s = formatError({ - message: e.message + originalError: e }, true); expect(s).to.eql(e.serialize());