Skip to content

Commit

Permalink
feat(query): added options.rawErrors to query() method
Browse files Browse the repository at this point in the history
This option causes all errors from the underlying connection/database library
to be propagated unformatted and unmodified. Use this for lesser common errors
sequelize can't parse or in case you perfer to see the full raw errors.
  • Loading branch information
joaoe committed Jan 21, 2022
1 parent 20379dc commit a16cfa3
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 0 deletions.
23 changes: 23 additions & 0 deletions lib/dialects/abstract/query.js
Expand Up @@ -23,6 +23,14 @@ class AbstractQuery {
...options,
};
this.checkLoggingOption();

if (options.rawErrors) {
// The default implementation in AbstractQuery just returns the same
// error object. By overidding this.formatError, this saves every dialect
// having to check for options.rawErrors in their own formatError
// implementations.
this.formatError = AbstractQuery.prototype.formatError;
}
}

/**
Expand Down Expand Up @@ -109,6 +117,21 @@ class AbstractQuery {
return [sql, []];
}

/**
* Formats a raw database error from the database library into a common Sequelize exception.
*
* @param {Error} error The exception object.
* @param {object} errStack The stack trace that started the database query.
* @returns {BaseError} the new formatted error object.
*/
formatError(error, errStack) {
// Default implementation, no formatting.
// Each dialect overrides this method to parse errors from their respective the database engines.
error.stack = errStack;

return error;
}

/**
* Execute the passed sql query.
*
Expand Down
1 change: 1 addition & 0 deletions lib/sequelize.js
Expand Up @@ -518,6 +518,7 @@ class Sequelize {
* @param {boolean} [options.supportsSearchPath] If false do not prepend the query with the search_path (Postgres only)
* @param {boolean} [options.mapToModel=false] Map returned fields to model's fields if `options.model` or `options.instance` is present. Mapping will occur before building the model instance.
* @param {object} [options.fieldMap] Map returned fields to arbitrary names for `SELECT` query type.
* @param {boolean} [options.rawErrors=false] Set to `true` to cause errors coming from the underlying connection/database library to be propagated unmodified and unformatted. Else, the default behavior (=true) is to reinterpret errors as sequelize.errors.BaseError objects.
*
* @returns {Promise}
*
Expand Down
11 changes: 11 additions & 0 deletions test/integration/sequelize/query.test.js
Expand Up @@ -365,6 +365,17 @@ describe(Support.getTestDialectTeaser('Sequelize'), () => {
await this.UserVisit.sync({ force: true });
});

it('emits raw errors if requested', async function () {
const sql = 'SELECT 1 FROM NotFoundTable';

await expect(this.sequelize.query(sql, { rawErrors: false }))
.to.eventually.be.rejectedWith(DatabaseError);

await expect(this.sequelize.query(sql, { rawErrors: true }))
.to.eventually.be.rejected
.and.not.be.an.instanceOf(DatabaseError);
});

it('emits full stacktraces for generic database error', async function () {
let error = null;
try {
Expand Down

0 comments on commit a16cfa3

Please sign in to comment.