From 4b49f500fce156b164c757d8f17be2338f767c82 Mon Sep 17 00:00:00 2001 From: dcodeIO Date: Sat, 11 Mar 2017 06:25:59 +0100 Subject: [PATCH] Other: Trying out a more aggressive aproach for custom error subclasses --- google/{protobuf => }/LICENSE | 0 google/{protobuf => }/README.md | 0 src/decoder.js | 2 +- src/util/minimal.js | 65 ++++++++++++++++++++++++++++++--- src/util/protocolerror.js | 51 -------------------------- 5 files changed, 61 insertions(+), 57 deletions(-) rename google/{protobuf => }/LICENSE (100%) rename google/{protobuf => }/README.md (100%) delete mode 100644 src/util/protocolerror.js diff --git a/google/protobuf/LICENSE b/google/LICENSE similarity index 100% rename from google/protobuf/LICENSE rename to google/LICENSE diff --git a/google/protobuf/README.md b/google/README.md similarity index 100% rename from google/protobuf/README.md rename to google/README.md diff --git a/src/decoder.js b/src/decoder.js index 9dcb10bff..25202c8ed 100644 --- a/src/decoder.js +++ b/src/decoder.js @@ -95,7 +95,7 @@ function decoder(mtype) { var rfield = mtype._fieldsArray[i]; if (rfield.required) gen ("if(!m.hasOwnProperty(%j))", rfield.name) - ("throw util.ProtocolError(%j,m)", missing(rfield)); + ("throw util.ProtocolError(%j,{instance:m})", missing(rfield)); } return gen diff --git a/src/util/minimal.js b/src/util/minimal.js index bef16dd74..b5cce3d9e 100644 --- a/src/util/minimal.js +++ b/src/util/minimal.js @@ -22,9 +22,6 @@ util.pool = require("@protobufjs/pool"); // utility to work with the low and high bits of a 64 bit value util.LongBits = require("./longbits"); -// error subclass indicating a protocol specifc error -util.ProtocolError = require("./protocolerror"); - /** * An immuable empty array. * @memberof util @@ -181,17 +178,20 @@ util.longFromHash = function longFromHash(hash, unsigned) { /** * Merges the properties of the source object into the destination object. + * @memberof util * @param {Object.} dst Destination object * @param {Object.} src Source object * @param {boolean} [ifNotSet=false] Merges only if the key is not already set * @returns {Object.} Destination object */ -util.merge = function merge(dst, src, ifNotSet) { // used by converters +function merge(dst, src, ifNotSet) { // used by converters for (var keys = Object.keys(src), i = 0; i < keys.length; ++i) if (dst[keys[i]] === undefined || !ifNotSet) dst[keys[i]] = src[keys[i]]; return dst; -}; +} + +util.merge = merge; /** * Converts the first character of a string to lower case. @@ -202,6 +202,61 @@ util.lcFirst = function lcFirst(str) { return str.charAt(0).toLowerCase() + str.substring(1); }; +/** + * Creates a custom error constructor. + * @memberof util + * @param {string} name Error name + * @returns {function} Custom error constructor + */ +function newError(name) { + + function CustomError(message, properties) { + + if (!(this instanceof CustomError)) + return new CustomError(message, properties); + + Error.call(this, message); + Object.defineProperty(this, "message", { get: function() { return message; } }); + if (Error.captureStackTrace) + Error.captureStackTrace(this, CustomError); + else + Object.defineProperty(this, "stack", { value: (new Error()).stack || "" }); + + if (properties) + merge(this, properties); + } + + (CustomError.prototype = Object.create(Error.prototype)).constructor = CustomError; + + Object.defineProperty(CustomError.prototype, "name", { get: function() { return name; } }); + + CustomError.prototype.toString = function toString() { + return this.name + ": " + this.message; + }; + + return CustomError; +} + +util.newError = newError; + +/** + * Constructs a new protocol error. + * @classdesc Error subclass indicating a protocol specifc error. + * @memberof util + * @extends Error + * @constructor + * @param {string} message Error message + * @param {Object.=} properties Additional properties + * @example + * try { + * MyMessage.decode(someBuffer); // throws if required fields are missing + * } catch (e) { + * if (e instanceof ProtocolError && e.instance) + * console.log("decoded so far: " + JSON.stringify(e.instance)); + * } + */ +util.ProtocolError = newError("ProtocolError"); + /** * Builds a getter for a oneof's present field name. * @param {string[]} fieldNames Field names diff --git a/src/util/protocolerror.js b/src/util/protocolerror.js deleted file mode 100644 index c967489f9..000000000 --- a/src/util/protocolerror.js +++ /dev/null @@ -1,51 +0,0 @@ -"use strict"; -module.exports = ProtocolError; - -// extends Error -(ProtocolError.prototype = Object.create(Error.prototype)).constructor = Error; - -/** - * Constructs a new protocol error. - * @classdesc Error subclass indicating a protocol specifc error. - * @memberof util - * @extends Error - * @constructor - * @param {string} message Error message - * @param {Message=} instance So far decoded message instance, if applicable - * @example - * try { - * MyMessage.decode(someBuffer); // throws if required fields are missing - * } catch (e) { - * if (e instanceof ProtocolError && e.instance) - * console.log("decoded so far: " + JSON.stringify(e.instance)); - * } - */ -function ProtocolError(message, instance) { - - if (!(this instanceof ProtocolError)) - return new ProtocolError(message, instance); - - /** - * Error message. - * @type {string} - */ - this.message = message; - - /** - * Stack trace. - * @type {string} - */ - this.stack = Error(message).stack || /* istanbul ignore next */ ""; // not supported in IE9/Safari5 - - /** - * So far decoded message instance, if applicable. - * @type {?Message} - */ - this.instance = instance || null; -} - -/** - * Error name (ProtocolError). - * @type {string} - */ -ProtocolError.prototype.name = "ProtocolError";