From aa13a35193d747adc7eed20de80a8cb929a5a973 Mon Sep 17 00:00:00 2001 From: Tobias Gurtzick Date: Thu, 16 May 2019 13:33:16 +0200 Subject: [PATCH] feat(error handling): added advanced error handling and rollback Signed-off-by: Tobias Gurtzick --- lib/executors/versioned/v2.js | 19 ++++++++---- lib/learn.js | 55 ++++++++++++++++++++++++++++------- 2 files changed, 59 insertions(+), 15 deletions(-) diff --git a/lib/executors/versioned/v2.js b/lib/executors/versioned/v2.js index 08a0d63c..2958101e 100644 --- a/lib/executors/versioned/v2.js +++ b/lib/executors/versioned/v2.js @@ -2,6 +2,7 @@ const Promise = require('bluebird'); const State = require('../../state'); +const log = require('db-migrate-shared').log; const Learn = require('../../learn'); const Chain = require('../../chain'); const StateTravel = require('../../methods/v2/statetravel'); @@ -49,11 +50,19 @@ const execUnit = { chain.addChain(Migrate); await State.startMigration(context._driver, file, context.internals); - await _file.migrate(chain, { - options: context.internals.safeOptions, - seedLink: context.seedLink, - dbm: context.internals.safeOptions.dbmigrate - }); + try { + await _file.migrate(chain, { + options: context.internals.safeOptions, + seedLink: context.seedLink, + dbm: context.internals.safeOptions.dbmigrate + }); + } catch (err) { + log.error( + 'An error occured. No alternative failure strategy defined. Rolling back!' + ); + await execUnit.down(context, driver, file); + throw err; + } return Promise.promisify(context.writeMigrationRecord.bind(context))(file); return execUnit.learn(context, driver, file); diff --git a/lib/learn.js b/lib/learn.js index 0e33eb78..39d2e328 100644 --- a/lib/learn.js +++ b/lib/learn.js @@ -3,6 +3,7 @@ const Shadow = require('./driver/shadow'); class STD { constructor ({ schema, modSchema: mod }, driver) { + this.validations = {}; this.driver = driver; this.indizies = schema.i; this.schema = schema.c; @@ -98,16 +99,50 @@ class STD { let alter = {}; if (this.schema[t]) { if (this.schema[t][c].notNull === true) { - if (this.driver._meta.supports.optionParam === true) { - throw new Error( - 'Can not drop a notNull column without providing a' + - ' recreation strategy.' - ); - } else { - throw new Error( - 'This driver does not support optionParameters which are' + - ' required to provide a recreation strategy.' - ); + if (this.validations.columnStrategies !== true) { + if ( + this.driver._meta && + this.driver._meta.supports && + this.driver._meta.supports.optionParam === true + ) { + /** + * This is a validation only, no action will be taken unless throwing + * errors. + * + * The driver needs to respect the options properly. + */ + switch (o.columnStrategy) { + case 'defaultValue': + break; + case 'delay': + break; + default: + if (!o.columnStrategy) { + throw new Error( + 'Can not drop a notNull column without providing a' + + ' recreation strategy.' + ); + } + throw new Error( + `There is no such column recreation strategy "${ + o.columnStrategy + }!"` + ); + } + } else { + throw new Error( + 'This driver does not support optionParameters which are' + + ' required to provide a recreation strategy.' + ); + } + + if (!this.driver._meta.supports.columnStrategies) { + throw new Error( + 'This driver does not support column recreation strategies.' + ); + } + + this.validations.columnStrategies = true; } } this.modS[t] = {};