Last active
April 12, 2024 16:13
-
-
Save mltsy/629d2b5b703f14e3e97eb8396518cfad to your computer and use it in GitHub Desktop.
Monkey Patch for the unfriendly errors thrown by Sequelize 6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* This monkey patch fixes an error reporting issue with sequelize errors in tests, | |
* which was fixed in Sequelize v7, but hasn't been back-ported to Sequelize v6. | |
* See https://github.com/sequelize/sequelize/issues/14807#issuecomment-1854398131 | |
* | |
* It should only be used in the test env, to make Sequelize error messages show up. | |
* This can be removed when we upgrade to Sequelize 7, or when the issue is fixed in v6. | |
*/ | |
const { Sequelize } = require('sequelize') | |
const sequelizeVersion = Sequelize['version'] || '6.x.x' // doesn't (currently) exist in v6 | |
const major = Number(sequelizeVersion.split('.')[0]) | |
if (major >= 7) { | |
console.warn( | |
'This patch was probably made redundant in Sequelize v7, you should check!' | |
) | |
} | |
/** | |
* @param {Sequelize} instance An instance of Sequelize | |
* @returns {Sequelize} Monkey-patched Sequelize instance that throws Jest-compatible errors | |
*/ | |
function monkeyPatchSequelizeErrorsForJest(instance) { | |
if (typeof jest === 'undefined') return instance | |
const origQueryFunc = instance.query | |
instance.query = async function query(...args) { | |
let result | |
try { | |
result = await origQueryFunc.apply(this, args) | |
} catch (err) { | |
throw fixSequelizeError(err) | |
} | |
return result | |
} | |
return instance | |
} | |
const isSequelizeError = e => | |
e instanceof Error && e.name.startsWith('Sequelize') | |
const fixSequelizeError = error => { | |
if (!isSequelizeError(error)) return error | |
let { message } = error.parent | |
if (error.sql) { | |
message += '\nSQL: ' + error.sql | |
} | |
if (error.parameters) { | |
const stringifiedParameters = JSON.stringify(error.parameters) | |
if ( | |
stringifiedParameters !== 'undefined' && | |
stringifiedParameters !== '{}' | |
) { | |
message += '\nParameters: ' + stringifiedParameters | |
} | |
} | |
message += '\n' + error.stack | |
error.message = message | |
Error.captureStackTrace(error) | |
return error | |
} | |
module.exports = monkeyPatchSequelizeErrorsForJest |
Updated so that the error thrown is actually the original error class, not a new invented one (since validating the class of the error thrown may be important for some tests)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
A workaround for sequelize/sequelize#14807
This should cause errors to have the correct stack trace and error name, such that Jest will print out the error that occurred.
To use this, just import it wherever you define your Sequelize DB, and do something like:
(It will always reference the monkeyPatch file as the source of the error, but you can look down the stack trace to find the real source)