diff --git a/lib/errors/index.js b/lib/errors/index.js index 5ff2af2..6e54d72 100644 --- a/lib/errors/index.js +++ b/lib/errors/index.js @@ -1,7 +1,8 @@ 'use strict'; -exports.ErrorManager = require('./error-manager'); - -exports.SfPersistanceError = require('./sf-persistance-error'); -exports.SyncModulePullError = require('./sync-module-pull-error'); -exports.Validation = require('./validation'); +module.exports = { + ErrorManager: require('./error-manager'), + SyncError: require('./error-manager'), + ...require('./validation'), + ...require('./operational') +}; diff --git a/lib/errors/operational/index.js b/lib/errors/operational/index.js new file mode 100644 index 0000000..f5d5db0 --- /dev/null +++ b/lib/errors/operational/index.js @@ -0,0 +1,5 @@ +'use strict'; + +exports.OperationalError = require('./operational-error'); +exports.SfPersistanceError = require('./sf-persistance-error'); +exports.SyncModulePullError = require('./sync-module-pull-error'); diff --git a/lib/errors/operational/operational-error.js b/lib/errors/operational/operational-error.js new file mode 100644 index 0000000..31b0f42 --- /dev/null +++ b/lib/errors/operational/operational-error.js @@ -0,0 +1,5 @@ +'use strict'; + +const SyncError = require('../sync-error'); + +module.exports = class OperationalError extends SyncError {}; diff --git a/lib/errors/sf-persistance-error.js b/lib/errors/operational/sf-persistance-error.js similarity index 78% rename from lib/errors/sf-persistance-error.js rename to lib/errors/operational/sf-persistance-error.js index 0997e55..3bfc21d 100644 --- a/lib/errors/sf-persistance-error.js +++ b/lib/errors/operational/sf-persistance-error.js @@ -2,14 +2,14 @@ const find = require('lodash/find'); const matchAll = require('match-all'); +const OperationalError = require('./operational-error'); -class SfPersistanceError { +class SfPersistanceError extends OperationalError { constructor(original, Model, entries) { - this.name = 'SfPersistanceError'; + super(`Unable to persist fetched ${Model.name} salesforce entries`); this.original = original; this.Model = Model; this.entries = entries; - this.message = `Unable to persist fetched ${Model.name} salesforce entries`; if (!this[original.name]) throw original; this.failingField = this[original.name](); diff --git a/lib/errors/operational/sync-module-pull-error.js b/lib/errors/operational/sync-module-pull-error.js new file mode 100644 index 0000000..a4dcafd --- /dev/null +++ b/lib/errors/operational/sync-module-pull-error.js @@ -0,0 +1,13 @@ +'use strict'; + +const OperationalError = require('./operational-error'); + +class SyncModulePullError extends OperationalError { + constructor(original, SyncModule) { + super(`Error pulling ${SyncModule.Model.name} salesforce records`); + this.original = original; + this.SyncModule = SyncModule; + } +} + +module.exports = SyncModulePullError; diff --git a/lib/errors/sync-error.js b/lib/errors/sync-error.js new file mode 100644 index 0000000..78a667b --- /dev/null +++ b/lib/errors/sync-error.js @@ -0,0 +1,12 @@ +'use strict'; + +class SyncError extends Error { + constructor(message) { + super(message); + this.createdAt = Date.now(); + this.name = this.constructor.name; + Error.captureStackTrace(this, this.constructor); + } +} + +module.exports = SyncError; diff --git a/lib/errors/sync-module-pull-error.js b/lib/errors/sync-module-pull-error.js deleted file mode 100644 index 4cfef24..0000000 --- a/lib/errors/sync-module-pull-error.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; - -class SyncModulePullError { - constructor(original, SyncModule) { - this.name = 'SyncModulePullError'; - this.original = original; - this.SyncModule = SyncModule; - this.message = `Error pulling ${SyncModule.Model.name} salesforce records`; - } -} - -module.exports = SyncModulePullError; diff --git a/lib/errors/validation/attribute-error.js b/lib/errors/validation/attribute-error.js index c8ea7aa..a25421d 100644 --- a/lib/errors/validation/attribute-error.js +++ b/lib/errors/validation/attribute-error.js @@ -2,16 +2,12 @@ const ValidationError = require('./validation-error'); -class AttributeError extends ValidationError { +class AttributeValidationError extends ValidationError { constructor(originalError) { - super(originalError.instance); - this.name = 'AttributeError'; - this.original = originalError; - } - - get message() { - return `${this.name}: ${this.original.message}; ${this.instanceInfo}`; + const { instance, message } = originalError; + super(instance, message); + this.originalError = originalError; } } -module.exports = AttributeError; +module.exports = AttributeValidationError; diff --git a/lib/errors/validation/consumable-error.js b/lib/errors/validation/consumable-error.js index cf84593..ddb3f4e 100644 --- a/lib/errors/validation/consumable-error.js +++ b/lib/errors/validation/consumable-error.js @@ -2,16 +2,15 @@ const ValidationError = require('./validation-error'); -class ConsumableError extends ValidationError { +class ConsumableValidationError extends ValidationError { constructor(instance, association) { - super(...arguments); - this.name = 'ConsumableError'; + super(instance, getMessage(association)); this.association = association; } - - get message() { - return `${this.name}: Invalid consumable association: ${this.association.associationAccessor}; ${this.instanceInfo}`; - } } -module.exports = ConsumableError; +module.exports = ConsumableValidationError; + +function getMessage(association) { + return `Invalid consumable association: ${association.associationAccessor}`; +} diff --git a/lib/errors/validation/domain-error.js b/lib/errors/validation/domain-error.js index 63a3d89..a211e8d 100644 --- a/lib/errors/validation/domain-error.js +++ b/lib/errors/validation/domain-error.js @@ -2,16 +2,11 @@ const ValidationError = require('./validation-error'); -class DomainError extends ValidationError { - constructor(instance, originalMessage) { - super(...arguments); - this.name = 'DomainError'; - this.originalMessage = originalMessage; - } - - get message() { - return `${this.name}: ${this.originalMessage}; ${this.instanceInfo}`; +class DomainValidationError extends ValidationError { + constructor(instance, message) { + super(instance, message); + this.originalMessage = message; } } -module.exports = DomainError; +module.exports = DomainValidationError; diff --git a/lib/errors/validation/fk-error.js b/lib/errors/validation/fk-error.js index 3db83e8..d877c0e 100644 --- a/lib/errors/validation/fk-error.js +++ b/lib/errors/validation/fk-error.js @@ -2,21 +2,19 @@ const ValidationError = require('./validation-error'); -class ValidationFkError extends ValidationError { +class ForeignKeyValidationError extends ValidationError { constructor(instance, association) { - super(...arguments); - this.name = 'ValidationFkError'; - this.alias = association.associationAccessor; - this.fk = association.identifier; + const alias = association.associationAccessor; + const fk = association.identifier; + const value = instance[fk]; + const message = getMessage(alias, fk, value); + super(instance, message); + Object.assign(this, { alias, fk, value }); } +} - get message() { - return `${this.name}: No ${this.alias} found for ${this.fk}: ${this.value}; ${this.instanceInfo}`; - } +module.exports = ForeignKeyValidationError; - get value() { - return this.instance[this.fk]; - } +function getMessage(alias, fk, value) { + return `No ${alias} found for ${fk}: ${value}`; } - -module.exports = ValidationFkError; diff --git a/lib/errors/validation/uniqueness-error.js b/lib/errors/validation/uniqueness-error.js index 769faf0..5e1ddc0 100644 --- a/lib/errors/validation/uniqueness-error.js +++ b/lib/errors/validation/uniqueness-error.js @@ -5,20 +5,16 @@ const map = require('lodash/map'); const transform = require('lodash/transform'); const ValidationError = require('./validation-error'); -class ValidationUniquenessError extends ValidationError { - constructor(instance, index) { - super(...arguments); - this.name = 'ValidationUniquenessError'; - this.index = index; - this.values = parseValues(instance, index); - } - - get message() { - return `${this.name}: duplicate value for ${this.index.join()}: ${map(this.values).join()}; ${this.instanceInfo}`; +class UniquenessValidationError extends ValidationError { + constructor(instance, index = []) { + const values = parseValues(instance, index); + const message = getMessage(index, values); + super(instance, message); + Object.assign(this, { values, index }); } } -module.exports = ValidationUniquenessError; +module.exports = UniquenessValidationError; function parseValues(instance, index) { return transform(index, (acc, it) => { @@ -26,3 +22,7 @@ function parseValues(instance, index) { acc[it] = instance[attribute]; }, {}); } + +function getMessage(index, values) { + return `Duplicate value for ${index.join()}: ${map(values).join()}`; +} diff --git a/lib/errors/validation/validation-error.js b/lib/errors/validation/validation-error.js index 86bb4e6..19f9c71 100644 --- a/lib/errors/validation/validation-error.js +++ b/lib/errors/validation/validation-error.js @@ -1,22 +1,19 @@ 'use strict'; -class ValidationError { - constructor(instance) { - this.name = 'ValidationError'; - this.instance = instance; - } - - get id() { - return this.instance.id; - } +const SyncError = require('../sync-error'); - get modelName() { - return this.instance.constructor.name; - } - - get instanceInfo() { - return `${this.modelName} id: ${this.id}`; +class ValidationError extends SyncError { + constructor(instance, message = '') { + const modelName = instance.constructor.name; + const instanceId = instance.id; + super(getMessage(message, modelName, instanceId)); + Object.assign(this, { instance, instanceId, modelName }); } } module.exports = ValidationError; + +function getMessage(message, modelName, id) { + const instanceInfo = `${modelName} id: ${id}`; + return [message, instanceInfo].filter(Boolean).join('; '); +} diff --git a/lib/sync/sync-module-validator.js b/lib/sync/sync-module-validator.js index 6576616..742a6d9 100644 --- a/lib/sync/sync-module-validator.js +++ b/lib/sync/sync-module-validator.js @@ -1,6 +1,6 @@ 'use strict'; -const errors = require('../errors/validation'); +const errors = require('../errors'); const filter = require('lodash/filter'); const get = require('lodash/get'); const map = require('lodash/map'); diff --git a/lib/sync/sync-module.js b/lib/sync/sync-module.js index d15a90f..5cfff62 100644 --- a/lib/sync/sync-module.js +++ b/lib/sync/sync-module.js @@ -1,6 +1,6 @@ 'use strict'; -const errors = require('../errors'); +const { ErrorManager, SfPersistanceError, SyncModulePullError } = require('../errors'); const filter = require('lodash/filter'); const invokeMap = require('lodash/invokeMap'); const Loader = require('../utils/loader'); @@ -9,8 +9,6 @@ const partition = require('lodash/partition'); const Promise = require('bluebird'); const SyncModuleValidator = require('./sync-module-validator'); -const { ErrorManager, SfPersistanceError, SyncModulePullError } = errors; - class SyncModule { constructor({ Model, sync }) { this.Model = Model;