Skip to content
This repository was archived by the owner on Oct 1, 2021. It is now read-only.

Commit c93c732

Browse files
committed
feat: when error occures save last succesfull migration version
1 parent 724d02b commit c93c732

File tree

3 files changed

+21
-3
lines changed

3 files changed

+21
-3
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ Migrations are one of those things that can be extremely painful on users. At th
102102
- Tests. Migrations have to be well tested.
103103
- To Spec. The tools must conform to the spec.
104104

105+
If your migration has several parts, it should be fail-proof enough that if one part of migration fails the previous changes
106+
are reverted before propagating the error. If possible then the outcome should be consistent repo so it migration could
107+
be run again.
108+
105109
#### Architecture of migrations
106110

107111
All migrations are placed in the `/migrations` folder. Each folder there represents one migration that follows the migration

src/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,14 @@ async function migrate (path, { toVersion, ignoreLock = false, repoOptions, onPr
9898
try {
9999
if (!isDryRun) await migration.migrate(path, repoOptions, isBrowser)
100100
} catch (e) {
101+
const lastSuccessfullyMigratedVersion = migration.version - 1
102+
log(`An exception was raised during execution of migration. Setting the repo\'s version to last successfully migrated version: ${lastSuccessfullyMigratedVersion}`)
103+
await repoVersion.setVersion(path, lastSuccessfullyMigratedVersion)
104+
101105
e.message = `During migration to version ${migration.version} exception was raised: ${e.message}`
102106
throw e
103107
}
108+
104109
typeof onProgress === 'function' && onProgress(migration, counter, totalMigrations) // Reports on migration process
105110
log(`Migrating to version ${migration.version} finished`)
106111
}
@@ -187,9 +192,14 @@ async function revert (path, toVersion, { ignoreLock = false, repoOptions, onPro
187192
try {
188193
if (!isDryRun) await migration.revert(path, repoOptions, isBrowser)
189194
} catch (e) {
195+
const lastSuccessfullyRevertedVersion = migration.version
196+
log(`An exception was raised during execution of migration. Setting the repo\'s version to last successfully reverted version: ${lastSuccessfullyRevertedVersion}`)
197+
await repoVersion.setVersion(path, lastSuccessfullyRevertedVersion)
198+
190199
e.message = `During reversion to version ${migration.version} exception was raised: ${e.message}`
191200
throw e
192201
}
202+
193203
typeof onProgress === 'function' && onProgress(migration, counter, totalMigrations) // Reports on migration process
194204
log(`Reverting to version ${migration.version} finished`)
195205
}

test/index.spec.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,16 @@ describe('index.js', () => {
249249
it('should unlock repo when error is thrown', async () => {
250250
getVersionStub.returns(4)
251251
const options = createOptions()
252-
options.migrations[3].revert = sinon.stub().rejects()
252+
options.migrations[2].revert = sinon.stub().rejects()
253253

254254
await expect(migrator.revert('/some/path', 2, options))
255255
.to.eventually.be.rejected()
256256

257257
expect(lockCloseStub.calledOnce).to.be.true()
258258
expect(lockStub.calledOnce).to.be.true()
259-
expect(setVersionStub.called).to.be.false()
259+
260+
// The last successfully reverted migration should be set as repo's version
261+
expect(setVersionStub.calledOnceWith('/some/path', 3)).to.be.true()
260262
})
261263
})
262264

@@ -388,7 +390,9 @@ describe('index.js', () => {
388390

389391
expect(lockCloseStub.calledOnce).to.be.true()
390392
expect(lockStub.calledOnce).to.be.true()
391-
expect(setVersionStub.called).to.be.false()
393+
394+
// The last successfully migrated migration should be set as repo's version
395+
expect(setVersionStub.calledOnceWith('/some/path', 3)).to.be.true()
392396
})
393397
})
394398
})

0 commit comments

Comments
 (0)