diff --git a/lib/dialects/mssql/async-queue.js b/lib/dialects/mssql/async-queue.js deleted file mode 100644 index adebefc08a8d..000000000000 --- a/lib/dialects/mssql/async-queue.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict'; - -const BaseError = require('../../errors/base-error'); -const ConnectionError = require('../../errors/connection-error'); - -/** - * Thrown when a connection to a database is closed while an operation is in progress - */ -class AsyncQueueError extends BaseError { - constructor(message) { - super(message); - this.name = 'SequelizeAsyncQueueError'; - } -} - -exports.AsyncQueueError = AsyncQueueError; - -class AsyncQueue { - constructor() { - this.previous = Promise.resolve(); - this.closed = false; - this.rejectCurrent = () => {}; - } - close() { - this.closed = true; - this.rejectCurrent(new ConnectionError(new AsyncQueueError('the connection was closed before this query could finish executing'))); - } - enqueue(asyncFunction) { - // This outer promise might seems superflous since down below we return asyncFunction().then(resolve, reject). - // However, this ensures that this.previous will never be a rejected promise so the queue will - // always keep going, while still communicating rejection from asyncFunction to the user. - return new Promise((resolve, reject) => { - this.previous = this.previous.then( - () => { - this.rejectCurrent = reject; - if (this.closed) { - return reject(new ConnectionError(new AsyncQueueError('the connection was closed before this query could be executed'))); - } - return asyncFunction().then(resolve, reject); - } - ); - }); - } -} - -exports.default = AsyncQueue; diff --git a/lib/dialects/mssql/async-queue.ts b/lib/dialects/mssql/async-queue.ts new file mode 100644 index 000000000000..6fe77fa4df88 --- /dev/null +++ b/lib/dialects/mssql/async-queue.ts @@ -0,0 +1,59 @@ +import { BaseError, ConnectionError } from '../../errors'; + +/** + * Thrown when a connection to a database is closed while an operation is in progress + */ +export class AsyncQueueError extends BaseError { + constructor(message: string) { + super(message); + this.name = 'SequelizeAsyncQueueError'; + } +} + +class AsyncQueue { + previous: Promise; + closed: boolean; + rejectCurrent: (reason?: any) => void; + + constructor() { + this.previous = Promise.resolve(); + this.closed = false; + this.rejectCurrent = () => { + /** do nothing */ + }; + } + + close() { + this.closed = true; + this.rejectCurrent( + new ConnectionError( + new AsyncQueueError( + 'the connection was closed before this query could finish executing' + ) + ) + ); + } + + enqueue(asyncFunction: (...args: any[]) => Promise) { + // This outer promise might seems superflous since down below we return asyncFunction().then(resolve, reject). + // However, this ensures that this.previous will never be a rejected promise so the queue will + // always keep going, while still communicating rejection from asyncFunction to the user. + return new Promise((resolve, reject) => { + this.previous = this.previous.then(() => { + this.rejectCurrent = reject; + if (this.closed) { + return reject( + new ConnectionError( + new AsyncQueueError( + 'the connection was closed before this query could be executed' + ) + ) + ); + } + return asyncFunction().then(resolve, reject); + }); + }); + } +} + +export default AsyncQueue; diff --git a/lib/errors/aggregate-error.js b/lib/errors/aggregate-error.js deleted file mode 100644 index 4a6eb94a4311..000000000000 --- a/lib/errors/aggregate-error.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict'; - -const BaseError = require('./base-error'); - -/** - * A wrapper for multiple Errors - * - * @param {Error[]} [errors] Array of errors - * - * @property errors {Error[]} - */ -class AggregateError extends BaseError { - constructor(errors) { - super(); - this.errors = errors; - this.name = 'AggregateError'; - } - - toString() { - const message = `AggregateError of:\n${ - this.errors.map(error => - error === this - ? '[Circular AggregateError]' - : error instanceof AggregateError - ? String(error).replace(/\n$/, '').replace(/^/mg, ' ') - : String(error).replace(/^/mg, ' ').substring(2) - - ).join('\n') - }\n`; - return message; - } -} - -module.exports = AggregateError; diff --git a/lib/errors/aggregate-error.ts b/lib/errors/aggregate-error.ts new file mode 100644 index 000000000000..59a69c13eaf6 --- /dev/null +++ b/lib/errors/aggregate-error.ts @@ -0,0 +1,31 @@ +import BaseError from './base-error'; + +/** + * A wrapper for multiple Errors + * + * @param errors Array of errors + */ +class AggregateError extends BaseError { + errors: Array; + + constructor(errors: Array) { + super(); + this.errors = errors; + this.name = 'AggregateError'; + } + + toString(): string { + const message = `AggregateError of:\n${this.errors + .map((error: Error | AggregateError) => + error === this + ? '[Circular AggregateError]' + : error instanceof AggregateError + ? String(error).replace(/\n$/, '').replace(/^/gm, ' ') + : String(error).replace(/^/gm, ' ').substring(2) + ) + .join('\n')}\n`; + return message; + } +} + +export default AggregateError; diff --git a/lib/errors/association-error.js b/lib/errors/association-error.ts similarity index 63% rename from lib/errors/association-error.js rename to lib/errors/association-error.ts index d4ef83f9ae52..de7c17acd9b0 100644 --- a/lib/errors/association-error.js +++ b/lib/errors/association-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const BaseError = require('./base-error'); +import BaseError from './base-error'; /** * Thrown when an association is improperly constructed (see message for details) */ class AssociationError extends BaseError { - constructor(message) { + constructor(message: string) { super(message); this.name = 'SequelizeAssociationError'; } } -module.exports = AssociationError; +export default AssociationError; diff --git a/lib/errors/base-error.js b/lib/errors/base-error.ts similarity index 50% rename from lib/errors/base-error.js rename to lib/errors/base-error.ts index ef0060113513..74cca10f295a 100644 --- a/lib/errors/base-error.js +++ b/lib/errors/base-error.ts @@ -1,4 +1,17 @@ -'use strict'; +export interface ErrorOptions { + stack?: string; +} + +export interface CommonErrorProperties { + /** The database specific error which triggered this one */ + readonly parent: Error; + + /** The database specific error which triggered this one */ + readonly original: Error; + + /** The SQL that triggered the error */ + readonly sql: string; +} /** * Sequelize provides a host of custom error classes, to allow you to do easier debugging. All of these errors are exposed on the sequelize object and the sequelize constructor. @@ -7,11 +20,11 @@ * This means that errors can be accessed using `Sequelize.ValidationError` * The Base Error all Sequelize Errors inherit from. */ -class BaseError extends Error { - constructor(message) { +abstract class BaseError extends Error { + constructor(message?: string) { super(message); this.name = 'SequelizeBaseError'; } } -module.exports = BaseError; +export default BaseError; diff --git a/lib/errors/bulk-record-error.js b/lib/errors/bulk-record-error.js deleted file mode 100644 index c095754040ae..000000000000 --- a/lib/errors/bulk-record-error.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; - -const BaseError = require('./base-error'); - -/** - * Thrown when bulk operation fails, it represent per record level error. - * Used with AggregateError - * - * @param {Error} error Error for a given record/instance - * @param {object} record DAO instance that error belongs to - */ -class BulkRecordError extends BaseError { - constructor(error, record) { - super(error.message); - this.name = 'SequelizeBulkRecordError'; - this.errors = error; - this.record = record; - } -} - -module.exports = BulkRecordError; diff --git a/lib/errors/bulk-record-error.ts b/lib/errors/bulk-record-error.ts new file mode 100644 index 000000000000..ad5ede0b9cda --- /dev/null +++ b/lib/errors/bulk-record-error.ts @@ -0,0 +1,23 @@ +import BaseError from './base-error'; +import type { Model } from '../../types/lib/model'; + +/** + * Thrown when bulk operation fails, it represent per record level error. + * Used with AggregateError + * + * @param error Error for a given record/instance + * @param record DAO instance that error belongs to + */ +class BulkRecordError extends BaseError { + errors: Error; + record: Model; + + constructor(error: Error, record: Model) { + super(error.message); + this.name = 'SequelizeBulkRecordError'; + this.errors = error; + this.record = record; + } +} + +export default BulkRecordError; diff --git a/lib/errors/connection-error.js b/lib/errors/connection-error.ts similarity index 52% rename from lib/errors/connection-error.js rename to lib/errors/connection-error.ts index 4a3a8a38e989..d8f3e16f22af 100644 --- a/lib/errors/connection-error.js +++ b/lib/errors/connection-error.ts @@ -1,22 +1,19 @@ -'use strict'; - -const BaseError = require('./base-error'); +import BaseError from './base-error'; /** * A base class for all connection related errors. */ class ConnectionError extends BaseError { - constructor(parent) { + /** The connection specific error which triggered this one */ + parent: Error; + original: Error; + + constructor(parent: Error) { super(parent ? parent.message : ''); this.name = 'SequelizeConnectionError'; - /** - * The connection specific error which triggered this one - * - * @type {Error} - */ this.parent = parent; this.original = parent; } } -module.exports = ConnectionError; +export default ConnectionError; diff --git a/lib/errors/connection/access-denied-error.js b/lib/errors/connection/access-denied-error.ts similarity index 61% rename from lib/errors/connection/access-denied-error.js rename to lib/errors/connection/access-denied-error.ts index c6bc2e8f72f8..03e216e60e13 100644 --- a/lib/errors/connection/access-denied-error.js +++ b/lib/errors/connection/access-denied-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const ConnectionError = require('./../connection-error'); +import ConnectionError from './../connection-error'; /** * Thrown when a connection to a database is refused due to insufficient privileges */ class AccessDeniedError extends ConnectionError { - constructor(parent) { + constructor(parent: Error) { super(parent); this.name = 'SequelizeAccessDeniedError'; } } -module.exports = AccessDeniedError; +export default AccessDeniedError; diff --git a/lib/errors/connection/connection-acquire-timeout-error.js b/lib/errors/connection/connection-acquire-timeout-error.ts similarity index 59% rename from lib/errors/connection/connection-acquire-timeout-error.js rename to lib/errors/connection/connection-acquire-timeout-error.ts index 661707b93116..6704e6418cce 100644 --- a/lib/errors/connection/connection-acquire-timeout-error.js +++ b/lib/errors/connection/connection-acquire-timeout-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const ConnectionError = require('./../connection-error'); +import ConnectionError from '../connection-error'; /** * Thrown when connection is not acquired due to timeout */ class ConnectionAcquireTimeoutError extends ConnectionError { - constructor(parent) { + constructor(parent: Error) { super(parent); this.name = 'SequelizeConnectionAcquireTimeoutError'; } } -module.exports = ConnectionAcquireTimeoutError; +export default ConnectionAcquireTimeoutError; diff --git a/lib/errors/connection/connection-refused-error.js b/lib/errors/connection/connection-refused-error.ts similarity index 58% rename from lib/errors/connection/connection-refused-error.js rename to lib/errors/connection/connection-refused-error.ts index 0c689c11aab6..9f5e32349127 100644 --- a/lib/errors/connection/connection-refused-error.js +++ b/lib/errors/connection/connection-refused-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const ConnectionError = require('./../connection-error'); +import ConnectionError from '../connection-error'; /** * Thrown when a connection to a database is refused */ class ConnectionRefusedError extends ConnectionError { - constructor(parent) { + constructor(parent: Error) { super(parent); this.name = 'SequelizeConnectionRefusedError'; } } -module.exports = ConnectionRefusedError; +export default ConnectionRefusedError; diff --git a/lib/errors/connection/connection-timed-out-error.js b/lib/errors/connection/connection-timed-out-error.ts similarity index 58% rename from lib/errors/connection/connection-timed-out-error.js rename to lib/errors/connection/connection-timed-out-error.ts index 2a2004b9ab70..1b74a3661e3b 100644 --- a/lib/errors/connection/connection-timed-out-error.js +++ b/lib/errors/connection/connection-timed-out-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const ConnectionError = require('./../connection-error'); +import ConnectionError from '../connection-error'; /** * Thrown when a connection to a database times out */ class ConnectionTimedOutError extends ConnectionError { - constructor(parent) { + constructor(parent: Error) { super(parent); this.name = 'SequelizeConnectionTimedOutError'; } } -module.exports = ConnectionTimedOutError; +export default ConnectionTimedOutError; diff --git a/lib/errors/connection/host-not-found-error.js b/lib/errors/connection/host-not-found-error.ts similarity index 60% rename from lib/errors/connection/host-not-found-error.js rename to lib/errors/connection/host-not-found-error.ts index c0493aff9280..da9600e776f2 100644 --- a/lib/errors/connection/host-not-found-error.js +++ b/lib/errors/connection/host-not-found-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const ConnectionError = require('./../connection-error'); +import ConnectionError from '../connection-error'; /** * Thrown when a connection to a database has a hostname that was not found */ class HostNotFoundError extends ConnectionError { - constructor(parent) { + constructor(parent: Error) { super(parent); this.name = 'SequelizeHostNotFoundError'; } } -module.exports = HostNotFoundError; +export default HostNotFoundError; diff --git a/lib/errors/connection/host-not-reachable-error.js b/lib/errors/connection/host-not-reachable-error.ts similarity index 61% rename from lib/errors/connection/host-not-reachable-error.js rename to lib/errors/connection/host-not-reachable-error.ts index a6bab854f143..c9cc53689e27 100644 --- a/lib/errors/connection/host-not-reachable-error.js +++ b/lib/errors/connection/host-not-reachable-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const ConnectionError = require('./../connection-error'); +import ConnectionError from '../connection-error'; /** * Thrown when a connection to a database has a hostname that was not reachable */ class HostNotReachableError extends ConnectionError { - constructor(parent) { + constructor(parent: Error) { super(parent); this.name = 'SequelizeHostNotReachableError'; } } -module.exports = HostNotReachableError; +export default HostNotReachableError; diff --git a/lib/errors/connection/invalid-connection-error.js b/lib/errors/connection/invalid-connection-error.ts similarity index 63% rename from lib/errors/connection/invalid-connection-error.js rename to lib/errors/connection/invalid-connection-error.ts index 538303f31c38..7d16c67e834b 100644 --- a/lib/errors/connection/invalid-connection-error.js +++ b/lib/errors/connection/invalid-connection-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const ConnectionError = require('./../connection-error'); +import ConnectionError from '../connection-error'; /** * Thrown when a connection to a database has invalid values for any of the connection parameters */ class InvalidConnectionError extends ConnectionError { - constructor(parent) { + constructor(parent: Error) { super(parent); this.name = 'SequelizeInvalidConnectionError'; } } -module.exports = InvalidConnectionError; +export default InvalidConnectionError; diff --git a/lib/errors/database-error.js b/lib/errors/database-error.js deleted file mode 100644 index ec09cad182b4..000000000000 --- a/lib/errors/database-error.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict'; - -const BaseError = require('./base-error'); - -/** - * A base class for all database related errors. - */ -class DatabaseError extends BaseError { - constructor(parent, options) { - super(parent.message); - this.name = 'SequelizeDatabaseError'; - /** - * @type {Error} - */ - this.parent = parent; - /** - * @type {Error} - */ - this.original = parent; - /** - * The SQL that triggered the error - * - * @type {string} - */ - this.sql = parent.sql; - /** - * The parameters for the sql that triggered the error - * - * @type {Array} - */ - this.parameters = parent.parameters; - /** - * The stacktrace can be overridden if the original stacktrace isn't very good - * - * @type {string} - */ - if (options && options.stack) { - this.stack = options.stack; - } - } -} - -module.exports = DatabaseError; diff --git a/lib/errors/database-error.ts b/lib/errors/database-error.ts new file mode 100644 index 000000000000..d4dd00a474ef --- /dev/null +++ b/lib/errors/database-error.ts @@ -0,0 +1,43 @@ +import BaseError, { CommonErrorProperties, ErrorOptions } from './base-error'; + +export interface DatabaseErrorParent + extends Error, + Pick { + /** The parameters for the sql that triggered the error */ + readonly parameters?: object; +} + +export interface DatabaseErrorSubclassOptions extends ErrorOptions { + parent?: DatabaseErrorParent; + message?: string; +} + +/** + * A base class for all database related errors. + */ +class DatabaseError + extends BaseError + implements DatabaseErrorParent, CommonErrorProperties +{ + parent: Error; + original: Error; + sql: string; + parameters: object; + + constructor(parent: DatabaseErrorParent, options: ErrorOptions = {}) { + super(parent.message); + this.name = 'SequelizeDatabaseError'; + + this.parent = parent; + this.original = parent; + + this.sql = parent.sql; + this.parameters = parent.parameters ?? {}; + + if (options.stack) { + this.stack = options.stack; + } + } +} + +export default DatabaseError; diff --git a/lib/errors/database/exclusion-constraint-error.js b/lib/errors/database/exclusion-constraint-error.js deleted file mode 100644 index 66ced0e5b9b5..000000000000 --- a/lib/errors/database/exclusion-constraint-error.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - -const DatabaseError = require('./../database-error'); - -/** - * Thrown when an exclusion constraint is violated in the database - */ -class ExclusionConstraintError extends DatabaseError { - constructor(options) { - options = options || {}; - options.parent = options.parent || { sql: '' }; - - super(options.parent, { stack: options.stack }); - this.name = 'SequelizeExclusionConstraintError'; - - this.message = options.message || options.parent.message || ''; - this.constraint = options.constraint; - this.fields = options.fields; - this.table = options.table; - } -} - -module.exports = ExclusionConstraintError; diff --git a/lib/errors/database/exclusion-constraint-error.ts b/lib/errors/database/exclusion-constraint-error.ts new file mode 100644 index 000000000000..715bba245826 --- /dev/null +++ b/lib/errors/database/exclusion-constraint-error.ts @@ -0,0 +1,36 @@ +import DatabaseError, { DatabaseErrorSubclassOptions } from '../database-error'; + +interface ExclusionConstraintErrorOptions { + constraint: string; + fields: Record; + table: string; +} + +/** + * Thrown when an exclusion constraint is violated in the database + */ +class ExclusionConstraintError + extends DatabaseError + implements ExclusionConstraintErrorOptions +{ + constraint: string; + fields: Record; + table: string; + + constructor( + options: DatabaseErrorSubclassOptions & ExclusionConstraintErrorOptions + ) { + options = options || {}; + options.parent = options.parent || { sql: '', name: '', message: '' }; + + super(options.parent, { stack: options.stack }); + this.name = 'SequelizeExclusionConstraintError'; + + this.message = options.message || options.parent.message || ''; + this.constraint = options.constraint; + this.fields = options.fields; + this.table = options.table; + } +} + +export default ExclusionConstraintError; diff --git a/lib/errors/database/foreign-key-constraint-error.js b/lib/errors/database/foreign-key-constraint-error.js deleted file mode 100644 index a3acba352234..000000000000 --- a/lib/errors/database/foreign-key-constraint-error.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -const DatabaseError = require('./../database-error'); - -/** - * Thrown when a foreign key constraint is violated in the database - */ -class ForeignKeyConstraintError extends DatabaseError { - constructor(options) { - options = options || {}; - options.parent = options.parent || { sql: '' }; - - super(options.parent, { stack: options.stack }); - this.name = 'SequelizeForeignKeyConstraintError'; - - this.message = options.message || options.parent.message || 'Database Error'; - this.fields = options.fields; - this.table = options.table; - this.value = options.value; - this.index = options.index; - this.reltype = options.reltype; - } -} - -module.exports = ForeignKeyConstraintError; diff --git a/lib/errors/database/foreign-key-constraint-error.ts b/lib/errors/database/foreign-key-constraint-error.ts new file mode 100644 index 000000000000..8ffb38cfdc15 --- /dev/null +++ b/lib/errors/database/foreign-key-constraint-error.ts @@ -0,0 +1,45 @@ +import DatabaseError, { DatabaseErrorSubclassOptions } from '../database-error'; + +export enum RelationshipType { + parent = 'parent', + child = 'child', +} + +interface ForeignKeyConstraintErrorOptions { + table: string; + fields: { [field: string]: string }; + value: unknown; + index: string; + reltype: RelationshipType; +} + +/** + * Thrown when a foreign key constraint is violated in the database + */ +class ForeignKeyConstraintError extends DatabaseError { + table: string; + fields: { [field: string]: string }; + value: unknown; + index: string; + reltype: RelationshipType; + + constructor( + options: ForeignKeyConstraintErrorOptions & DatabaseErrorSubclassOptions + ) { + options = options || {}; + options.parent = options.parent || { sql: '', name: '', message: '' }; + + super(options.parent, { stack: options.stack }); + this.name = 'SequelizeForeignKeyConstraintError'; + + this.message = + options.message || options.parent.message || 'Database Error'; + this.fields = options.fields; + this.table = options.table; + this.value = options.value; + this.index = options.index; + this.reltype = options.reltype; + } +} + +export default ForeignKeyConstraintError; diff --git a/lib/errors/database/timeout-error.js b/lib/errors/database/timeout-error.js deleted file mode 100644 index 2342c1ab3d14..000000000000 --- a/lib/errors/database/timeout-error.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; - -const DatabaseError = require('./../database-error'); - -/** - * Thrown when a database query times out because of a deadlock - */ -class TimeoutError extends DatabaseError { - constructor(parent, options) { - super(parent, options); - this.name = 'SequelizeTimeoutError'; - } -} - -module.exports = TimeoutError; diff --git a/lib/errors/database/timeout-error.ts b/lib/errors/database/timeout-error.ts new file mode 100644 index 000000000000..17506ec4f47a --- /dev/null +++ b/lib/errors/database/timeout-error.ts @@ -0,0 +1,14 @@ +import { ErrorOptions } from '../base-error'; +import DatabaseError, { DatabaseErrorParent } from '../database-error'; + +/** + * Thrown when a database query times out because of a deadlock + */ +class TimeoutError extends DatabaseError { + constructor(parent: DatabaseErrorParent, options: ErrorOptions = {}) { + super(parent, options); + this.name = 'SequelizeTimeoutError'; + } +} + +export default TimeoutError; diff --git a/lib/errors/database/unknown-constraint-error.js b/lib/errors/database/unknown-constraint-error.js deleted file mode 100644 index 0c1be5d47a15..000000000000 --- a/lib/errors/database/unknown-constraint-error.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict'; - -const DatabaseError = require('./../database-error'); - -/** - * Thrown when constraint name is not found in the database - */ -class UnknownConstraintError extends DatabaseError { - constructor(options) { - options = options || {}; - options.parent = options.parent || { sql: '' }; - - super(options.parent, { stack: options.stack }); - this.name = 'SequelizeUnknownConstraintError'; - - this.message = options.message || 'The specified constraint does not exist'; - this.constraint = options.constraint; - this.fields = options.fields; - this.table = options.table; - } -} - -module.exports = UnknownConstraintError; diff --git a/lib/errors/database/unknown-constraint-error.ts b/lib/errors/database/unknown-constraint-error.ts new file mode 100644 index 000000000000..69d1ff0c2b1b --- /dev/null +++ b/lib/errors/database/unknown-constraint-error.ts @@ -0,0 +1,36 @@ +import DatabaseError, { DatabaseErrorSubclassOptions } from '../database-error'; + +interface UnknownConstraintErrorOptions { + constraint: string; + fields: Record; + table: string; +} + +/** + * Thrown when constraint name is not found in the database + */ +class UnknownConstraintError + extends DatabaseError + implements UnknownConstraintErrorOptions +{ + constraint: string; + fields: Record; + table: string; + + constructor( + options: UnknownConstraintErrorOptions & DatabaseErrorSubclassOptions + ) { + options = options || {}; + options.parent = options.parent || { sql: '', name: '', message: '' }; + + super(options.parent, { stack: options.stack }); + this.name = 'SequelizeUnknownConstraintError'; + + this.message = options.message || 'The specified constraint does not exist'; + this.constraint = options.constraint; + this.fields = options.fields; + this.table = options.table; + } +} + +export default UnknownConstraintError; diff --git a/lib/errors/eager-loading-error.js b/lib/errors/eager-loading-error.ts similarity index 64% rename from lib/errors/eager-loading-error.js rename to lib/errors/eager-loading-error.ts index 928af9c447bd..315033f20a20 100644 --- a/lib/errors/eager-loading-error.js +++ b/lib/errors/eager-loading-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const BaseError = require('./base-error'); +import BaseError from './base-error'; /** * Thrown when an include statement is improperly constructed (see message for details) */ class EagerLoadingError extends BaseError { - constructor(message) { + constructor(message: string) { super(message); this.name = 'SequelizeEagerLoadingError'; } } -module.exports = EagerLoadingError; +export default EagerLoadingError; diff --git a/lib/errors/empty-result-error.js b/lib/errors/empty-result-error.ts similarity index 65% rename from lib/errors/empty-result-error.js rename to lib/errors/empty-result-error.ts index c967817d0690..9b3e768a7530 100644 --- a/lib/errors/empty-result-error.js +++ b/lib/errors/empty-result-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const BaseError = require('./base-error'); +import BaseError from './base-error'; /** * Thrown when a record was not found, Usually used with rejectOnEmpty mode (see message for details) */ class EmptyResultError extends BaseError { - constructor(message) { + constructor(message: string) { super(message); this.name = 'SequelizeEmptyResultError'; } } -module.exports = EmptyResultError; +export default EmptyResultError; diff --git a/lib/errors/index.js b/lib/errors/index.js deleted file mode 100644 index 16316a5acad4..000000000000 --- a/lib/errors/index.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; - -exports.BaseError = require('./base-error'); - -exports.AggregateError = require('./aggregate-error'); -exports.AsyncQueueError = require('../dialects/mssql/async-queue').AsyncQueueError; -exports.AssociationError = require('./association-error'); -exports.BulkRecordError = require('./bulk-record-error'); -exports.ConnectionError = require('./connection-error'); -exports.DatabaseError = require('./database-error'); -exports.EagerLoadingError = require('./eager-loading-error'); -exports.EmptyResultError = require('./empty-result-error'); -exports.InstanceError = require('./instance-error'); -exports.OptimisticLockError = require('./optimistic-lock-error'); -exports.QueryError = require('./query-error'); -exports.SequelizeScopeError = require('./sequelize-scope-error'); -exports.ValidationError = require('./validation-error'); -exports.ValidationErrorItem = exports.ValidationError.ValidationErrorItem; - -exports.AccessDeniedError = require('./connection/access-denied-error'); -exports.ConnectionAcquireTimeoutError = require('./connection/connection-acquire-timeout-error'); -exports.ConnectionRefusedError = require('./connection/connection-refused-error'); -exports.ConnectionTimedOutError = require('./connection/connection-timed-out-error'); -exports.HostNotFoundError = require('./connection/host-not-found-error'); -exports.HostNotReachableError = require('./connection/host-not-reachable-error'); -exports.InvalidConnectionError = require('./connection/invalid-connection-error'); - -exports.ExclusionConstraintError = require('./database/exclusion-constraint-error'); -exports.ForeignKeyConstraintError = require('./database/foreign-key-constraint-error'); -exports.TimeoutError = require('./database/timeout-error'); -exports.UnknownConstraintError = require('./database/unknown-constraint-error'); - -exports.UniqueConstraintError = require('./validation/unique-constraint-error'); diff --git a/lib/errors/index.ts b/lib/errors/index.ts new file mode 100644 index 000000000000..b99b247b3757 --- /dev/null +++ b/lib/errors/index.ts @@ -0,0 +1,36 @@ +export { default as BaseError } from './base-error'; + +export { default as DatabaseError } from './database-error'; +export { default as AggregateError } from './aggregate-error'; +export { default as AssociationError } from './association-error'; +export { default as BulkRecordError } from './bulk-record-error'; +export { default as ConnectionError } from './connection-error'; +export { default as EagerLoadingError } from './eager-loading-error'; +export { default as EmptyResultError } from './empty-result-error'; +export { default as InstanceError } from './instance-error'; +export { default as OptimisticLockError } from './optimistic-lock-error'; +export { default as QueryError } from './query-error'; +export { default as SequelizeScopeError } from './sequelize-scope-error'; +export { + default as ValidationError, + ValidationErrorItem, + ValidationErrorItemOrigin, + ValidationErrorItemType +} from './validation-error'; + +export { default as AccessDeniedError } from './connection/access-denied-error'; +export { default as ConnectionAcquireTimeoutError } from './connection/connection-acquire-timeout-error'; +export { default as ConnectionRefusedError } from './connection/connection-refused-error'; +export { default as ConnectionTimedOutError } from './connection/connection-timed-out-error'; +export { default as HostNotFoundError } from './connection/host-not-found-error'; +export { default as HostNotReachableError } from './connection/host-not-reachable-error'; +export { default as InvalidConnectionError } from './connection/invalid-connection-error'; + +export { default as ExclusionConstraintError } from './database/exclusion-constraint-error'; +export { default as ForeignKeyConstraintError } from './database/foreign-key-constraint-error'; +export { default as TimeoutError } from './database/timeout-error'; +export { default as UnknownConstraintError } from './database/unknown-constraint-error'; + +export { default as UniqueConstraintError } from './validation/unique-constraint-error'; + +export { AsyncQueueError } from '../dialects/mssql/async-queue'; diff --git a/lib/errors/instance-error.js b/lib/errors/instance-error.ts similarity index 64% rename from lib/errors/instance-error.js rename to lib/errors/instance-error.ts index 913ce1e3b3b7..253aadafeb0f 100644 --- a/lib/errors/instance-error.js +++ b/lib/errors/instance-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const BaseError = require('./base-error'); +import BaseError from './base-error'; /** * Thrown when a some problem occurred with Instance methods (see message for details) */ class InstanceError extends BaseError { - constructor(message) { + constructor(message: string) { super(message); this.name = 'SequelizeInstanceError'; } } -module.exports = InstanceError; +export default InstanceError; diff --git a/lib/errors/optimistic-lock-error.js b/lib/errors/optimistic-lock-error.js deleted file mode 100644 index 0c0ff3eb7db4..000000000000 --- a/lib/errors/optimistic-lock-error.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict'; - -const BaseError = require('./base-error'); - -/** - * Thrown when attempting to update a stale model instance - */ -class OptimisticLockError extends BaseError { - constructor(options) { - options = options || {}; - options.message = options.message || `Attempting to update a stale model instance: ${options.modelName}`; - super(options.message); - this.name = 'SequelizeOptimisticLockError'; - /** - * The name of the model on which the update was attempted - * - * @type {string} - */ - this.modelName = options.modelName; - /** - * The values of the attempted update - * - * @type {object} - */ - this.values = options.values; - /** - * - * @type {object} - */ - this.where = options.where; - } -} - -module.exports = OptimisticLockError; diff --git a/lib/errors/optimistic-lock-error.ts b/lib/errors/optimistic-lock-error.ts new file mode 100644 index 000000000000..17e6d025b52a --- /dev/null +++ b/lib/errors/optimistic-lock-error.ts @@ -0,0 +1,36 @@ +import BaseError from './base-error'; + +interface OptimisticLockErrorOptions { + message?: string; + + /** The name of the model on which the update was attempted */ + modelName?: string; + + /** The values of the attempted update */ + values?: Record; + where?: Record; +} + +/** + * Thrown when attempting to update a stale model instance + */ +class OptimisticLockError extends BaseError { + modelName?: string; + values?: Record; + where?: Record; + + constructor(options: OptimisticLockErrorOptions) { + options = options || {}; + options.message = + options.message || + `Attempting to update a stale model instance: ${options.modelName}`; + + super(options.message); + this.name = 'SequelizeOptimisticLockError'; + this.modelName = options.modelName; + this.values = options.values; + this.where = options.where; + } +} + +export default OptimisticLockError; diff --git a/lib/errors/query-error.js b/lib/errors/query-error.ts similarity index 62% rename from lib/errors/query-error.js rename to lib/errors/query-error.ts index 3ec05cc3712a..4aff253b0a3c 100644 --- a/lib/errors/query-error.js +++ b/lib/errors/query-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const BaseError = require('./base-error'); +import BaseError from './base-error'; /** * Thrown when a query is passed invalid options (see message for details) */ class QueryError extends BaseError { - constructor(message) { + constructor(message: string) { super(message); this.name = 'SequelizeQueryError'; } } -module.exports = QueryError; +export default QueryError; diff --git a/lib/errors/sequelize-scope-error.js b/lib/errors/sequelize-scope-error.ts similarity index 56% rename from lib/errors/sequelize-scope-error.js rename to lib/errors/sequelize-scope-error.ts index f7a40ad58c71..b1b161a1c13c 100644 --- a/lib/errors/sequelize-scope-error.js +++ b/lib/errors/sequelize-scope-error.ts @@ -1,15 +1,13 @@ -'use strict'; - -const BaseError = require('./base-error'); +import BaseError from './base-error'; /** * Scope Error. Thrown when the sequelize cannot query the specified scope. */ class SequelizeScopeError extends BaseError { - constructor(parent) { - super(parent); + constructor(message: string) { + super(message); this.name = 'SequelizeScopeError'; } } -module.exports = SequelizeScopeError; +export default SequelizeScopeError; diff --git a/lib/errors/validation-error.js b/lib/errors/validation-error.js deleted file mode 100644 index 3e0d1095a8b2..000000000000 --- a/lib/errors/validation-error.js +++ /dev/null @@ -1,213 +0,0 @@ -'use strict'; - -const BaseError = require('./base-error'); - -/** - * Validation Error. Thrown when the sequelize validation has failed. The error contains an `errors` property, - * which is an array with 1 or more ValidationErrorItems, one for each validation that failed. - * - * @param {string} message Error message - * @param {Array} [errors] Array of ValidationErrorItem objects describing the validation errors - * - * @property errors {ValidationErrorItems[]} - */ -class ValidationError extends BaseError { - constructor(message, errors, options) { - super(message); - this.name = 'SequelizeValidationError'; - this.message = 'Validation Error'; - /** - * - * @type {ValidationErrorItem[]} - */ - this.errors = errors || []; - - // Use provided error message if available... - if (message) { - this.message = message; - - // ... otherwise create a concatenated message out of existing errors. - } else if (this.errors.length > 0 && this.errors[0].message) { - this.message = this.errors.map(err => `${err.type || err.origin}: ${err.message}`).join(',\n'); - } - - // Allow overriding the stack if the original stacktrace is uninformative - if (options && options.stack) { - this.stack = options.stack; - } - } - - /** - * Gets all validation error items for the path / field specified. - * - * @param {string} path The path to be checked for error items - * - * @returns {Array} Validation error items for the specified path - */ - get(path) { - return this.errors.reduce((reduced, error) => { - if (error.path === path) { - reduced.push(error); - } - return reduced; - }, []); - } -} - -/** - * Validation Error Item - * Instances of this class are included in the `ValidationError.errors` property. - */ -class ValidationErrorItem { - /** - * Creates a new ValidationError item. Instances of this class are included in the `ValidationError.errors` property. - * - * @param {string} [message] An error message - * @param {string} [type] The type/origin of the validation error - * @param {string} [path] The field that triggered the validation error - * @param {string} [value] The value that generated the error - * @param {Model} [instance] the DAO instance that caused the validation error - * @param {string} [validatorKey] a validation "key", used for identification - * @param {string} [fnName] property name of the BUILT-IN validator function that caused the validation error (e.g. "in" or "len"), if applicable - * @param {Array} [fnArgs] parameters used with the BUILT-IN validator function, if applicable - */ - constructor(message, type, path, value, instance, validatorKey, fnName, fnArgs) { - /** - * An error message - * - * @type {string} message - */ - this.message = message || ''; - - /** - * The type/origin of the validation error - * - * @type {string | null} - */ - this.type = null; - - /** - * The field that triggered the validation error - * - * @type {string | null} - */ - this.path = path || null; - - /** - * The value that generated the error - * - * @type {string | null} - */ - this.value = value !== undefined ? value : null; - - this.origin = null; - - /** - * The DAO instance that caused the validation error - * - * @type {Model | null} - */ - this.instance = instance || null; - - /** - * A validation "key", used for identification - * - * @type {string | null} - */ - this.validatorKey = validatorKey || null; - - /** - * Property name of the BUILT-IN validator function that caused the validation error (e.g. "in" or "len"), if applicable - * - * @type {string | null} - */ - this.validatorName = fnName || null; - - /** - * Parameters used with the BUILT-IN validator function, if applicable - * - * @type {Array} - */ - this.validatorArgs = fnArgs || []; - - if (type) { - if (ValidationErrorItem.Origins[ type ]) { - this.origin = type; - } else { - const lowercaseType = `${type}`.toLowerCase().trim(); - const realType = ValidationErrorItem.TypeStringMap[ lowercaseType ]; - - if (realType && ValidationErrorItem.Origins[ realType ]) { - this.origin = realType; - this.type = type; - } - } - } - - // This doesn't need captureStackTrace because it's not a subclass of Error - } - - /** - * return a lowercase, trimmed string "key" that identifies the validator. - * - * Note: the string will be empty if the instance has neither a valid `validatorKey` property nor a valid `validatorName` property - * - * @param {boolean} [useTypeAsNS=true] controls whether the returned value is "namespace", - * this parameter is ignored if the validator's `type` is not one of ValidationErrorItem.Origins - * @param {string} [NSSeparator='.'] a separator string for concatenating the namespace, must be not be empty, - * defaults to "." (fullstop). only used and validated if useTypeAsNS is TRUE. - * @throws {Error} thrown if NSSeparator is found to be invalid. - * @returns {string} - * - * @private - */ - getValidatorKey(useTypeAsNS, NSSeparator) { - const useTANS = useTypeAsNS === undefined || !!useTypeAsNS; - const NSSep = NSSeparator === undefined ? '.' : NSSeparator; - - const type = this.origin; - const key = this.validatorKey || this.validatorName; - const useNS = useTANS && type && ValidationErrorItem.Origins[ type ]; - - if (useNS && (typeof NSSep !== 'string' || !NSSep.length)) { - throw new Error('Invalid namespace separator given, must be a non-empty string'); - } - - if (!(typeof key === 'string' && key.length)) { - return ''; - } - - return (useNS ? [type, key].join(NSSep) : key).toLowerCase().trim(); - } -} - -/** - * An enum that defines valid ValidationErrorItem `origin` values - * - * @type {object} - * @property CORE {string} specifies errors that originate from the sequelize "core" - * @property DB {string} specifies validation errors that originate from the storage engine - * @property FUNCTION {string} specifies validation errors that originate from validator functions (both built-in and custom) defined for a given attribute - */ -ValidationErrorItem.Origins = { - CORE: 'CORE', - DB: 'DB', - FUNCTION: 'FUNCTION' -}; - -/** - * An object that is used internally by the `ValidationErrorItem` class - * that maps current `type` strings (as given to ValidationErrorItem.constructor()) to - * our new `origin` values. - * - * @type {object} - */ -ValidationErrorItem.TypeStringMap = { - 'notnull violation': 'CORE', - 'string violation': 'CORE', - 'unique violation': 'DB', - 'validation error': 'FUNCTION' -}; - -module.exports = ValidationError; -module.exports.ValidationErrorItem = ValidationErrorItem; diff --git a/lib/errors/validation-error.ts b/lib/errors/validation-error.ts new file mode 100644 index 000000000000..70e788e82d9a --- /dev/null +++ b/lib/errors/validation-error.ts @@ -0,0 +1,254 @@ +import BaseError, { ErrorOptions } from './base-error'; +import type { Model } from '../../types/lib/model'; + +/** + * An enum that is used internally by the `ValidationErrorItem` class + * that maps current `type` strings (as given to ValidationErrorItem.constructor()) to + * our new `origin` values. + */ +export enum ValidationErrorItemType { + 'notnull violation' = 'CORE', + 'string violation' = 'CORE', + 'unique violation' = 'DB', + 'validation error' = 'FUNCTION', +} + +/** + * An enum that defines valid ValidationErrorItem `origin` values + */ +export enum ValidationErrorItemOrigin { + /** + * specifies errors that originate from the sequelize "core" + */ + CORE = 'CORE', + + /** + * specifies validation errors that originate from the storage engine + */ + DB = 'DB', + + /** + * specifies validation errors that originate from validator functions (both built-in and custom) defined for a given attribute + */ + FUNCTION = 'FUNCTION', +} + +/** + * Validation Error Item + * Instances of this class are included in the `ValidationError.errors` property. + */ +export class ValidationErrorItem { + /** + * @deprecated Will be removed in v7 + */ + static TypeStringMap = ValidationErrorItemType; + + /** + * @deprecated Will be removed in v7 + */ + static Origins = ValidationErrorItemOrigin; + + /** + * An error message + */ + message: string; + + /** + * The type/origin of the validation error + */ + type: keyof typeof ValidationErrorItemType | null; + + /** + * The field that triggered the validation error + */ + path: string | null; + + /** + * The value that generated the error + */ + value: string | null; + + origin: keyof typeof ValidationErrorItemOrigin | null; + + /** + * The DAO instance that caused the validation error + */ + instance: Model | null; + + /** + * A validation "key", used for identification + */ + validatorKey: string | null; + + /** + * Property name of the BUILT-IN validator function that caused the validation error (e.g. "in" or "len"), if applicable + */ + validatorName: string | null; + + /** + * Parameters used with the BUILT-IN validator function, if applicable + */ + validatorArgs: unknown[]; + + /** + * Creates a new ValidationError item. Instances of this class are included in the `ValidationError.errors` property. + * + * @param message An error message + * @param type The type/origin of the validation error + * @param path The field that triggered the validation error + * @param value The value that generated the error + * @param instance the DAO instance that caused the validation error + * @param validatorKey a validation "key", used for identification + * @param fnName property name of the BUILT-IN validator function that caused the validation error (e.g. "in" or "len"), if applicable + * @param fnArgs parameters used with the BUILT-IN validator function, if applicable + */ + constructor( + message: string, + type: + | keyof typeof ValidationErrorItemType + | keyof typeof ValidationErrorItemOrigin, + path: string, + value: string, + instance: Model, + validatorKey: string, + fnName: string, + fnArgs: unknown[] + ) { + this.message = message || ''; + this.type = null; + this.path = path || null; + + this.value = value !== undefined ? value : null; + + this.origin = null; + + this.instance = instance || null; + + this.validatorKey = validatorKey || null; + + this.validatorName = fnName || null; + + this.validatorArgs = fnArgs || []; + + if (type) { + if (this.isValidationErrorItemOrigin(type)) { + this.origin = type; + } else { + const lowercaseType = this.normalizeString(type); + const realType = ValidationErrorItemType[lowercaseType]; + + if (realType && ValidationErrorItemOrigin[realType]) { + this.origin = realType; + this.type = type; + } + } + } + + // This doesn't need captureStackTrace because it's not a subclass of Error + } + + private isValidationErrorItemOrigin( + origin: + | keyof typeof ValidationErrorItemOrigin + | keyof typeof ValidationErrorItemType + ): origin is keyof typeof ValidationErrorItemOrigin { + return ( + ValidationErrorItemOrigin[ + origin as keyof typeof ValidationErrorItemOrigin + ] !== undefined + ); + } + + private normalizeString(str: T): T { + return str.toLowerCase().trim() as T; + } + + /** + * return a lowercase, trimmed string "key" that identifies the validator. + * + * Note: the string will be empty if the instance has neither a valid `validatorKey` property nor a valid `validatorName` property + * + * @param useTypeAsNS controls whether the returned value is "namespace", + * this parameter is ignored if the validator's `type` is not one of ValidationErrorItem.Origins + * @param NSSeparator a separator string for concatenating the namespace, must be not be empty, + * defaults to "." (fullstop). only used and validated if useTypeAsNS is TRUE. + * @throws {Error} thrown if NSSeparator is found to be invalid. + */ + getValidatorKey(useTypeAsNS: boolean, NSSeparator: string): string { + const useTANS = useTypeAsNS === undefined || !!useTypeAsNS; + const NSSep = NSSeparator === undefined ? '.' : NSSeparator; + + const type = this.origin; + const key = this.validatorKey || this.validatorName; + const useNS = useTANS && type && ValidationErrorItemOrigin[type]; + + if (useNS && (typeof NSSep !== 'string' || !NSSep.length)) { + throw new Error('Invalid namespace separator given, must be a non-empty string'); + } + + if (!(typeof key === 'string' && key.length)) { + return ''; + } + + return (useNS ? [this.origin, key].join(NSSep) : key).toLowerCase().trim(); + } +} + +/** + * Validation Error. Thrown when the sequelize validation has failed. The error contains an `errors` property, + * which is an array with 1 or more ValidationErrorItems, one for each validation that failed. + * + * @param message Error message + * @param errors Array of ValidationErrorItem objects describing the validation errors + */ +class ValidationError extends BaseError { + errors: ValidationErrorItem[]; + + constructor( + message: string, + errors: ValidationErrorItem[], + options: ErrorOptions = {} + ) { + super(message); + this.name = 'SequelizeValidationError'; + this.message = 'Validation Error'; + this.errors = errors || []; + + // Use provided error message if available... + if (message) { + this.message = message; + + // ... otherwise create a concatenated message out of existing errors. + } else if (this.errors.length > 0 && this.errors[0].message) { + this.message = this.errors + .map( + (err: ValidationErrorItem) => + `${err.type || err.origin}: ${err.message}` + ) + .join(',\n'); + } + + // Allow overriding the stack if the original stacktrace is uninformative + if (options.stack) { + this.stack = options.stack; + } + } + + /** + * Gets all validation error items for the path / field specified. + * + * @param {string} path The path to be checked for error items + * + * @returns {Array} Validation error items for the specified path + */ + get(path: string): ValidationErrorItem[] { + return this.errors.reduce((reduced, error) => { + if (error.path === path) { + reduced.push(error); + } + return reduced; + }, []); + } +} + +export default ValidationError; diff --git a/lib/errors/validation/unique-constraint-error.js b/lib/errors/validation/unique-constraint-error.js deleted file mode 100644 index e0978c09be36..000000000000 --- a/lib/errors/validation/unique-constraint-error.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -const ValidationError = require('./../validation-error'); - -/** - * Thrown when a unique constraint is violated in the database - */ -class UniqueConstraintError extends ValidationError { - constructor(options) { - options = options || {}; - options.parent = options.parent || { sql: '' }; - options.message = options.message || options.parent.message || 'Validation Error'; - options.errors = options.errors || {}; - super(options.message, options.errors, { stack: options.stack }); - - this.name = 'SequelizeUniqueConstraintError'; - this.errors = options.errors; - this.fields = options.fields; - this.parent = options.parent; - this.original = options.parent; - this.sql = options.parent.sql; - } -} - -module.exports = UniqueConstraintError; diff --git a/lib/errors/validation/unique-constraint-error.ts b/lib/errors/validation/unique-constraint-error.ts new file mode 100644 index 000000000000..11b208031b9b --- /dev/null +++ b/lib/errors/validation/unique-constraint-error.ts @@ -0,0 +1,45 @@ +import { CommonErrorProperties, ErrorOptions } from '../base-error'; +import ValidationError, { ValidationErrorItem } from '../validation-error'; + +interface UniqueConstraintErrorParent + extends Error, + Pick {} + +interface UniqueConstraintErrorOptions extends ErrorOptions { + parent?: UniqueConstraintErrorParent; + original?: UniqueConstraintErrorParent; + errors?: ValidationErrorItem[]; + fields?: Record; + message?: string; +} + +/** + * Thrown when a unique constraint is violated in the database + */ +class UniqueConstraintError + extends ValidationError + implements CommonErrorProperties +{ + parent: UniqueConstraintErrorParent; + original: UniqueConstraintErrorParent; + fields: Record; + sql: string; + + constructor(options: UniqueConstraintErrorOptions) { + options = options ?? {}; + options.parent = options.parent ?? { sql: '', name: '', message: '' }; + options.message = + options.message || options.parent.message || 'Validation Error'; + options.errors = options.errors ?? []; + super(options.message, options.errors, { stack: options.stack }); + + this.name = 'SequelizeUniqueConstraintError'; + this.errors = options.errors; + this.fields = options.fields ?? {}; + this.parent = options.parent; + this.original = options.parent; + this.sql = options.parent.sql; + } +} + +export default UniqueConstraintError; diff --git a/test/integration/error.test.js b/test/integration/error.test.js index 0f0304f80917..65bf544a83a7 100644 --- a/test/integration/error.test.js +++ b/test/integration/error.test.js @@ -152,6 +152,15 @@ describe(Support.getTestDialectTeaser('Sequelize Errors'), () => { }); }); + it('SequelizeValidationErrorItemOrigin is valid', () => { + const ORIGINS = Sequelize.ValidationErrorItemOrigin; + + expect(ORIGINS).to.have.property('CORE', 'CORE'); + expect(ORIGINS).to.have.property('DB', 'DB'); + expect(ORIGINS).to.have.property('FUNCTION', 'FUNCTION'); + + }); + it('SequelizeValidationErrorItem.Origins is valid', () => { const ORIGINS = Sequelize.ValidationErrorItem.Origins; diff --git a/test/integration/model/bulk-create.test.js b/test/integration/model/bulk-create.test.js index 9194c9fd7625..44ea01d5b4b7 100644 --- a/test/integration/model/bulk-create.test.js +++ b/test/integration/model/bulk-create.test.js @@ -310,7 +310,6 @@ describe(Support.getTestDialectTeaser('Model'), () => { const expectedValidationError = 'Validation len on code failed'; const expectedNotNullError = 'notNull Violation: Task.name cannot be null'; - expect(error).to.be.instanceof(AggregateError); expect(error.toString()).to.include(expectedValidationError) .and.to.include(expectedNotNullError); const { errors } = error;