Compare commits
10 Commits
899ea8dab9
...
4d3aef69b2
Author | SHA1 | Date |
---|---|---|
Sven Slootweg | 4d3aef69b2 | 4 years ago |
Sven Slootweg | 6239d9fe73 | 4 years ago |
Sven Slootweg | 147506f4b1 | 4 years ago |
Sven Slootweg | 888a023383 | 4 years ago |
Sven Slootweg | 6fbac562af | 4 years ago |
Sven Slootweg | 6a026cd4c1 | 4 years ago |
Sven Slootweg | ccae979451 | 4 years ago |
Sven Slootweg | abba82ad07 | 4 years ago |
Sven Slootweg | eb597cb699 | 4 years ago |
Sven Slootweg | 882ede36ed | 4 years ago |
@ -1,18 +0,0 @@
|
|||||||
var gulp = require("gulp");
|
|
||||||
var presetES2015 = require("@joepie91/gulp-preset-es2015");
|
|
||||||
|
|
||||||
var source = ["src/**/*.js"]
|
|
||||||
|
|
||||||
gulp.task('babel', function() {
|
|
||||||
return gulp.src(source)
|
|
||||||
.pipe(presetES2015({
|
|
||||||
basePath: __dirname
|
|
||||||
}))
|
|
||||||
.pipe(gulp.dest("lib/"));
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task("watch", function () {
|
|
||||||
gulp.watch(source, ["babel"]);
|
|
||||||
});
|
|
||||||
|
|
||||||
gulp.task("default", ["babel", "watch"]);
|
|
@ -1,3 +1,3 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = require("./lib");
|
module.exports = require("./src");
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
error: invalid input syntax for type timestamp with time zone: "{}"
|
||||||
|
insert into "transaction_events" ("field", "operator_id", "origin", "transaction_id", "type", "value") values ($1, DEFAULT, $2, $3, $4, $5), ($6, DEFAULT, $7, $8, $9, $10), ($11, DEFAULT, $12, $13, $14, $15), ($16, DEFAULT, $17, $18, $19, $20), ($21, DEFAULT, $22, $23, $24, $25), ($26, DEFAULT, $27, $28, $29, $30), ($31, DEFAULT, $32, $33, $34, $35), ($36, DEFAULT, $37, $38, $39, $40), ($41, DEFAULT, $42, $43, $44, $45), ($46, DEFAULT, $47, $48, $49, $50), ($51, DEFAULT, $52, $53, $54, $55), ($56, DEFAULT, $57, $58, $59, $60), ($61, DEFAULT, $62, $63, $64, $65), ($66, DEFAULT, $67, $68, $69, $70), ($71, DEFAULT, $72, $73, $74, DEFAULT) returning * - invalid input syntax for type json
|
@ -1,5 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const createError = require("create-error");
|
const { create } = require("error-chain");
|
||||||
|
|
||||||
module.exports = createError("DatabaseError");
|
module.exports = create("DatabaseError");
|
||||||
|
@ -1,59 +1,59 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const createError = require("create-error");
|
const { create } = require("error-chain");
|
||||||
const pgErrorCodes = require("pg-error-codes");
|
const pgErrorCodes = require("pg-error-codes");
|
||||||
|
|
||||||
const DatabaseError = require("../database-error.js");
|
const DatabaseError = require("../database-error.js");
|
||||||
const getColumns = require("../get-columns");
|
const getColumns = require("../get-columns");
|
||||||
const getValues = require("../get-values");
|
const getValues = require("../get-values");
|
||||||
|
|
||||||
let CheckConstraintViolationError = createError(DatabaseError, "CheckConstraintViolationError");
|
let CheckConstraintViolationError = create("CheckConstraintViolationError", { inheritsFrom: DatabaseError });
|
||||||
|
|
||||||
let messageRegex = /^(.+) - new row for relation "([^"]+)" violates check constraint "([^"]+)"$/;
|
let messageRegex = /^(.+) - new row for relation "([^"]+)" violates check constraint "([^"]+)"$/;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
error: CheckConstraintViolationError,
|
error: CheckConstraintViolationError,
|
||||||
errorName: "CheckConstraintViolationError",
|
errorName: "CheckConstraintViolationError",
|
||||||
check: function checkType(error) {
|
check: function checkType(error) {
|
||||||
return (
|
return (
|
||||||
// PostgreSQL (via `pg`):
|
// PostgreSQL (via `pg`):
|
||||||
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "23514")
|
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "23514")
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
convert: function convertError(error) {
|
convert: function convertError(error) {
|
||||||
let messageMatch = messageRegex.exec(error.message);
|
let messageMatch = messageRegex.exec(error.message);
|
||||||
|
|
||||||
if (messageMatch == null) {
|
if (messageMatch == null) {
|
||||||
throw new Error("Encountered unknown error format");
|
throw new Error("Encountered unknown error format");
|
||||||
}
|
}
|
||||||
|
|
||||||
let [_, query, table, constraint] = messageMatch;
|
let [_, query, _table, _constraint] = messageMatch;
|
||||||
|
|
||||||
let columns = getColumns(query);
|
let columns = getColumns(query);
|
||||||
|
|
||||||
let offendingColumn, message;
|
let offendingColumn, message;
|
||||||
|
|
||||||
if (columns != null) {
|
if (columns != null) {
|
||||||
/* This is the naming convention that Knex uses for .enum() in PostgreSQL */
|
/* This is the naming convention that Knex uses for .enum() in PostgreSQL */
|
||||||
offendingColumn = columns.find(column => {
|
offendingColumn = columns.find(column => {
|
||||||
return error.constraint === `${error.table}_${column}_check`
|
return error.constraint === `${error.table}_${column}_check`;
|
||||||
});
|
});
|
||||||
|
|
||||||
message = `Value violates the '${error.constraint}' constraint for the '${offendingColumn}' column in the '${error.table}' table`;
|
message = `Value violates the '${error.constraint}' constraint for the '${offendingColumn}' column in the '${error.table}' table`;
|
||||||
} else {
|
} else {
|
||||||
message = `Value violates the '${error.constraint}' constraint for the '${error.table}' table`;
|
message = `Value violates the '${error.constraint}' constraint for the '${error.table}' table`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CheckConstraintViolationError(message, {
|
return new CheckConstraintViolationError(message, {
|
||||||
originalError: error,
|
originalError: error,
|
||||||
pgCode: error.code,
|
pgCode: error.code,
|
||||||
code: pgErrorCodes[error.code],
|
code: pgErrorCodes[error.code],
|
||||||
query: query,
|
query: query,
|
||||||
schema: error.schema,
|
schema: error.schema,
|
||||||
table: error.table,
|
table: error.table,
|
||||||
column: offendingColumn,
|
column: offendingColumn,
|
||||||
constraint: error.constraint,
|
constraint: error.constraint,
|
||||||
values: getValues(error.detail)
|
values: getValues(error.detail)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,50 +1,50 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const createError = require("create-error");
|
const { create } = require("error-chain");
|
||||||
const pgErrorCodes = require("pg-error-codes");
|
const pgErrorCodes = require("pg-error-codes");
|
||||||
|
|
||||||
const DatabaseError = require("../database-error.js");
|
const DatabaseError = require("../database-error.js");
|
||||||
const getTable = require("../get-table");
|
const getTable = require("../get-table");
|
||||||
|
|
||||||
let EnumError = createError(DatabaseError, "EnumError");
|
let EnumError = create("EnumError", { inheritsFrom: DatabaseError });
|
||||||
|
|
||||||
let messageRegex = /^(.+) - invalid input value for enum ([^:]+): "([^"]+)"$/;
|
let messageRegex = /^(.+) - invalid input value for enum ([^:]+): "([^"]+)"$/;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
error: EnumError,
|
error: EnumError,
|
||||||
errorName: "EnumError",
|
errorName: "EnumError",
|
||||||
check: function checkType(error) {
|
check: function checkType(error) {
|
||||||
return (
|
return (
|
||||||
// PostgreSQL (via `pg`):
|
// PostgreSQL (via `pg`):
|
||||||
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "22P02" && error.message.includes("invalid input value for enum"))
|
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "22P02" && error.message.includes("invalid input value for enum"))
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
convert: function convertError(error) {
|
convert: function convertError(error) {
|
||||||
let messageMatch = messageRegex.exec(error.message);
|
let messageMatch = messageRegex.exec(error.message);
|
||||||
|
|
||||||
if (messageMatch == null) {
|
if (messageMatch == null) {
|
||||||
throw new Error("Encountered unknown error format");
|
throw new Error("Encountered unknown error format");
|
||||||
}
|
}
|
||||||
|
|
||||||
let [_, query, enumType, value] = messageMatch;
|
let [_, query, enumType, value] = messageMatch;
|
||||||
let table = getTable(query);
|
let table = getTable(query);
|
||||||
|
|
||||||
let message;
|
let message;
|
||||||
|
|
||||||
if (table != null) {
|
if (table != null) {
|
||||||
message = `Value '${value}' is not an allowed value for the ENUM type '${enumType}' (in table '${table}')`;
|
message = `Value '${value}' is not an allowed value for the ENUM type '${enumType}' (in table '${table}')`;
|
||||||
} else {
|
} else {
|
||||||
message = `Value '${value}' is not an allowed value for the ENUM type '${enumType}'`;
|
message = `Value '${value}' is not an allowed value for the ENUM type '${enumType}'`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new EnumError(message, {
|
return new EnumError(message, {
|
||||||
originalError: error,
|
originalError: error,
|
||||||
pgCode: error.code,
|
pgCode: error.code,
|
||||||
code: pgErrorCodes[error.code],
|
code: pgErrorCodes[error.code],
|
||||||
query: query,
|
query: query,
|
||||||
table: table,
|
table: table,
|
||||||
enumType: enumType,
|
enumType: enumType,
|
||||||
value: value
|
value: value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const createError = require("create-error");
|
const { create } = require("error-chain");
|
||||||
const pgErrorCodes = require("pg-error-codes");
|
const pgErrorCodes = require("pg-error-codes");
|
||||||
const DatabaseError = require("../database-error.js");
|
const DatabaseError = require("../database-error.js");
|
||||||
|
|
||||||
let ForeignKeyConstraintViolationError = createError(DatabaseError, "ForeignKeyConstraintViolationError");
|
let ForeignKeyConstraintViolationError = create("ForeignKeyConstraintViolationError", { inheritsFrom: DatabaseError });
|
||||||
|
|
||||||
let detailsRegex = /^Key \(([^\)]+)\)=\(([^\)]+)\) is not present in table "([^"]+)"\.$/;
|
let detailsRegex = /^Key \(([^\)]+)\)=\(([^\)]+)\) is not present in table "([^"]+)"\.$/;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
error: ForeignKeyConstraintViolationError,
|
error: ForeignKeyConstraintViolationError,
|
||||||
errorName: "ForeignKeyConstraintViolationError",
|
errorName: "ForeignKeyConstraintViolationError",
|
||||||
check: function checkType(error) {
|
check: function checkType(error) {
|
||||||
return (
|
return (
|
||||||
// PostgreSQL (via `pg`):
|
// PostgreSQL (via `pg`):
|
||||||
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "23503")
|
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "23503")
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
convert: function convertError(error) {
|
convert: function convertError(error) {
|
||||||
let [_, column, value, foreignTable] = detailsRegex.exec(error.detail);
|
let [_, column, value, foreignTable] = detailsRegex.exec(error.detail);
|
||||||
|
|
||||||
return new ForeignKeyConstraintViolationError(`Value for column '${column}' in table '${error.table}' refers to a non-existent key '${value}' in table '${foreignTable}'`, {
|
return new ForeignKeyConstraintViolationError(`Value for column '${column}' in table '${error.table}' refers to a non-existent key '${value}' in table '${foreignTable}'`, {
|
||||||
originalError: error,
|
originalError: error,
|
||||||
pgCode: error.code,
|
pgCode: error.code,
|
||||||
code: pgErrorCodes[error.code],
|
code: pgErrorCodes[error.code],
|
||||||
schema: error.schema,
|
schema: error.schema,
|
||||||
table: error.table,
|
table: error.table,
|
||||||
foreignTable: foreignTable,
|
foreignTable: foreignTable,
|
||||||
column: column,
|
column: column,
|
||||||
value: value,
|
value: value,
|
||||||
constraint: error.constraint
|
constraint: error.constraint
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,51 +1,53 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const createError = require("create-error");
|
const { create } = require("error-chain");
|
||||||
const pgErrorCodes = require("pg-error-codes");
|
const pgErrorCodes = require("pg-error-codes");
|
||||||
|
|
||||||
const DatabaseError = require("../database-error.js");
|
const DatabaseError = require("../database-error.js");
|
||||||
const getTable = require("../get-table");
|
const getTable = require("../get-table");
|
||||||
|
|
||||||
let InvalidTypeError = createError(DatabaseError, "InvalidTypeError");
|
let InvalidTypeError = create("InvalidTypeError", { inheritsFrom: DatabaseError });
|
||||||
|
|
||||||
/* NOTE: error messages vary. Eg. for boolean-type columns, it states "for type boolean", but for integer-type columns, it starts "for integer". */
|
/* NOTE: error messages vary. Eg. for boolean-type columns, it states "for type boolean", but for integer-type columns, it starts "for integer". */
|
||||||
let messageRegex = /^(.+) - invalid input syntax for(?: type)? ([^:]+): "([^"]+)"$/;
|
let messageRegex = /^(?:(.+) - )?invalid input syntax for(?: type)? ([^:]+)(?:: "(.+)")?$/;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
error: InvalidTypeError,
|
error: InvalidTypeError,
|
||||||
errorName: "InvalidTypeError",
|
errorName: "InvalidTypeError",
|
||||||
check: function checkType(error) {
|
check: function checkType(error) {
|
||||||
return (
|
return (
|
||||||
// PostgreSQL (via `pg`):
|
// PostgreSQL (via `pg`):
|
||||||
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "22P02" && error.message.includes("invalid input syntax for"))
|
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "22P02" && error.message.includes("invalid input syntax for"))
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
convert: function convertError(error) {
|
convert: function convertError(error) {
|
||||||
let messageMatch = messageRegex.exec(error.message);
|
let messageMatch = messageRegex.exec(error.message);
|
||||||
|
|
||||||
if (messageMatch == null) {
|
if (messageMatch == null) {
|
||||||
throw new Error("Encountered unknown error format");
|
/* TODO: Update other error parsing modules to display the original error message here as well. */
|
||||||
}
|
throw new Error(`Encountered unknown error format for error message: ${error.message}`);
|
||||||
|
}
|
||||||
let [_, query, expectedType, value] = messageMatch;
|
|
||||||
let table = getTable(query);
|
let [_, query, expectedType, value] = messageMatch;
|
||||||
|
let table = getTable(query);
|
||||||
let message;
|
|
||||||
|
let message;
|
||||||
if (table != null) {
|
|
||||||
message = `Value '${value}' is of the wrong type for a '${expectedType}'-type column (in table '${table}')`;
|
/* TODO: `value` can be undefined! */
|
||||||
} else {
|
if (table != null) {
|
||||||
message = `Value '${value}' is of the wrong type for a '${expectedType}'-type column '${enumType}'`;
|
message = `Value <${value}> is of the wrong type for a '${expectedType}'-type column (in table '${table}')`;
|
||||||
}
|
} else {
|
||||||
|
message = `Value <${value}> is of the wrong type for a '${expectedType}'-type column`;
|
||||||
return new InvalidTypeError(message, {
|
}
|
||||||
originalError: error,
|
|
||||||
pgCode: error.code,
|
return new InvalidTypeError(message, {
|
||||||
code: pgErrorCodes[error.code],
|
originalError: error,
|
||||||
query: query,
|
pgCode: error.code,
|
||||||
table: table,
|
code: pgErrorCodes[error.code],
|
||||||
expectedType: expectedType,
|
query: query,
|
||||||
value: value,
|
table: table,
|
||||||
});
|
expectedType: expectedType,
|
||||||
}
|
value: value,
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,36 +1,36 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const createError = require("create-error");
|
const { create } = require("error-chain");
|
||||||
const pgErrorCodes = require("pg-error-codes");
|
const pgErrorCodes = require("pg-error-codes");
|
||||||
|
|
||||||
const DatabaseError = require("../database-error.js");
|
const DatabaseError = require("../database-error.js");
|
||||||
const getValues = require("../get-values");
|
const getValues = require("../get-values");
|
||||||
|
|
||||||
let NotNullConstraintViolationError = createError(DatabaseError, "NotNullConstraintViolationError");
|
let NotNullConstraintViolationError = create("NotNullConstraintViolationError", { inheritsFrom: DatabaseError });
|
||||||
|
|
||||||
let messageRegex = /^(.+) - null value in column "([^"]+)" violates not-null constraint$/;
|
let messageRegex = /^(.+) - null value in column "([^"]+)" violates not-null constraint$/;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
error: NotNullConstraintViolationError,
|
error: NotNullConstraintViolationError,
|
||||||
errorName: "NotNullConstraintViolationError",
|
errorName: "NotNullConstraintViolationError",
|
||||||
check: function checkType(error) {
|
check: function checkType(error) {
|
||||||
return (
|
return (
|
||||||
// PostgreSQL (via `pg`):
|
// PostgreSQL (via `pg`):
|
||||||
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "23502")
|
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "23502")
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
convert: function convertError(error) {
|
convert: function convertError(error) {
|
||||||
let [_, query, column] = messageRegex.exec(error.message);
|
let [_, query, _column] = messageRegex.exec(error.message);
|
||||||
|
|
||||||
return new NotNullConstraintViolationError(`Missing required value for column '${error.column}' in table '${error.table}'`, {
|
return new NotNullConstraintViolationError(`Missing required value for column '${error.column}' in table '${error.table}'`, {
|
||||||
originalError: error,
|
originalError: error,
|
||||||
pgCode: error.code,
|
pgCode: error.code,
|
||||||
code: pgErrorCodes[error.code],
|
code: pgErrorCodes[error.code],
|
||||||
schema: error.schema,
|
schema: error.schema,
|
||||||
table: error.table,
|
table: error.table,
|
||||||
column: error.column,
|
column: error.column,
|
||||||
values: getValues(error.detail),
|
values: getValues(error.detail),
|
||||||
query: query
|
query: query
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,40 +1,48 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const createError = require("create-error");
|
const { create } = require("error-chain");
|
||||||
const pgErrorCodes = require("pg-error-codes");
|
const pgErrorCodes = require("pg-error-codes");
|
||||||
|
|
||||||
const DatabaseError = require("../database-error.js");
|
const DatabaseError = require("../database-error.js");
|
||||||
const getTable = require("../get-table");
|
|
||||||
|
|
||||||
let UndefinedColumnError = createError(DatabaseError, "UndefinedColumnError");
|
let UndefinedColumnError = create("UndefinedColumnError", { inheritsFrom: DatabaseError });
|
||||||
|
|
||||||
let messageRegex = /^(.+) - column "([^"]+)" of relation "([^"]+)" does not exist$/;
|
let messageRegex = /^(.+) - column "([^"]+)" (?:of relation "([^"]+)" )?does not exist$/;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
error: UndefinedColumnError,
|
error: UndefinedColumnError,
|
||||||
errorName: "UndefinedColumnError",
|
errorName: "UndefinedColumnError",
|
||||||
check: function checkType(error) {
|
check: function checkType(error) {
|
||||||
return (
|
return (
|
||||||
// PostgreSQL (via `pg`):
|
// PostgreSQL (via `pg`):
|
||||||
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "42703")
|
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "42703")
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
convert: function convertError(error) {
|
convert: function convertError(error) {
|
||||||
let messageMatch = messageRegex.exec(error.message);
|
let messageMatch = messageRegex.exec(error.message);
|
||||||
|
|
||||||
if (messageMatch == null) {
|
if (messageMatch == null) {
|
||||||
throw new Error("Encountered unknown error format");
|
throw new Error("Encountered unknown error format");
|
||||||
}
|
}
|
||||||
|
|
||||||
let [_, query, column, table] = messageMatch;
|
let [_, query, column, table] = messageMatch;
|
||||||
|
|
||||||
return new UndefinedColumnError(`The '${column}' column does not exist in the '${table}' table`, {
|
let errorMessage;
|
||||||
originalError: error,
|
|
||||||
pgCode: error.code,
|
if (table != null) {
|
||||||
code: pgErrorCodes[error.code],
|
errorMessage = `The '${column}' column does not exist in the '${table}' table`;
|
||||||
query: query,
|
} else {
|
||||||
table: table,
|
/* TODO: Maybe try to extract this from the query... somehow? */
|
||||||
column: column,
|
errorMessage = `The '${column}' column does not exist in (unknown table)`;
|
||||||
});
|
}
|
||||||
}
|
|
||||||
|
return new UndefinedColumnError(errorMessage, {
|
||||||
|
originalError: error,
|
||||||
|
pgCode: error.code,
|
||||||
|
code: pgErrorCodes[error.code],
|
||||||
|
query: query,
|
||||||
|
table: table,
|
||||||
|
column: column,
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,58 +1,58 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const createError = require("create-error");
|
const { create } = require("error-chain");
|
||||||
const pgErrorCodes = require("pg-error-codes");
|
const pgErrorCodes = require("pg-error-codes");
|
||||||
const DatabaseError = require("../database-error.js");
|
const DatabaseError = require("../database-error.js");
|
||||||
const splitValues = require("../split-values");
|
const splitValues = require("../split-values");
|
||||||
|
|
||||||
let UniqueConstraintViolationError = createError(DatabaseError, "UniqueConstraintViolationError");
|
let UniqueConstraintViolationError = create("UniqueConstraintViolationError", { inheritsFrom: DatabaseError });
|
||||||
|
|
||||||
let detailsRegex = /Key \(([^\)]+)\)=\(([^\)]+)\) already exists\./;
|
let detailsRegex = /Key \(([^\)]+)\)=\(([^\)]+)\) already exists\./;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
error: UniqueConstraintViolationError,
|
error: UniqueConstraintViolationError,
|
||||||
errorName: "UniqueConstraintViolationError",
|
errorName: "UniqueConstraintViolationError",
|
||||||
check: function checkType(error) {
|
check: function checkType(error) {
|
||||||
return (
|
return (
|
||||||
// PostgreSQL (via `pg`):
|
// PostgreSQL (via `pg`):
|
||||||
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "23505")
|
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "23505")
|
||||||
)
|
);
|
||||||
},
|
},
|
||||||
convert: function convertError(error) {
|
convert: function convertError(error) {
|
||||||
let [_, columnValue, valueValue] = detailsRegex.exec(error.detail);
|
let [_, columnValue, valueValue] = detailsRegex.exec(error.detail);
|
||||||
|
|
||||||
let column, columns, value, values, messageColumn, messageValue, isComposite;
|
let column, columns, value, values, messageColumn, messageValue, isComposite;
|
||||||
|
|
||||||
if (columnValue.includes(",")) {
|
if (columnValue.includes(",")) {
|
||||||
columns = splitValues(columnValue);
|
columns = splitValues(columnValue);
|
||||||
messageColumn = `columns [${columns.map(column => `'${column}'`).join(", ")}]`;
|
messageColumn = `columns [${columns.map(column => `'${column}'`).join(", ")}]`;
|
||||||
isComposite = true;
|
isComposite = true;
|
||||||
} else {
|
} else {
|
||||||
column = columnValue;
|
column = columnValue;
|
||||||
messageColumn = `column '${column}'`;
|
messageColumn = `column '${column}'`;
|
||||||
isComposite = false;
|
isComposite = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valueValue.includes(",")) {
|
if (valueValue.includes(",")) {
|
||||||
values = splitValues(valueValue);
|
values = splitValues(valueValue);
|
||||||
messageValue = `Values [${values.map(value => `'${value}'`).join(", ")}] already exist`;
|
messageValue = `Values [${values.map(value => `'${value}'`).join(", ")}] already exist`;
|
||||||
} else {
|
} else {
|
||||||
value = valueValue;
|
value = valueValue;
|
||||||
messageValue = `Value '${value}' already exists`;
|
messageValue = `Value '${value}' already exists`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new UniqueConstraintViolationError(`${messageValue} for ${messageColumn} in table '${error.table}'`, {
|
return new UniqueConstraintViolationError(`${messageValue} for ${messageColumn} in table '${error.table}'`, {
|
||||||
originalError: error,
|
originalError: error,
|
||||||
pgCode: error.code,
|
pgCode: error.code,
|
||||||
code: pgErrorCodes[error.code],
|
code: pgErrorCodes[error.code],
|
||||||
schema: error.schema,
|
schema: error.schema,
|
||||||
table: error.table,
|
table: error.table,
|
||||||
column: column,
|
column: column,
|
||||||
columns: columns,
|
columns: columns,
|
||||||
value: value,
|
value: value,
|
||||||
values: values,
|
values: values,
|
||||||
isComposite: isComposite,
|
isComposite: isComposite,
|
||||||
constraint: error.constraint
|
constraint: error.constraint
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
let detailsRegex = /^Failing row contains \(([^\)]+)\).$/;
|
let detailsRegex = /^Failing row contains \((.+)\).$/;
|
||||||
|
|
||||||
module.exports = function getValues(detail) {
|
module.exports = function getValues(detail) {
|
||||||
let detailsMatch = detailsRegex.exec(detail);
|
let detailsMatch = detailsRegex.exec(detail);
|
||||||
|
|
||||||
if (detailsMatch == null) {
|
if (detailsMatch == null) {
|
||||||
throw new Error("Could not determine values for query");
|
throw new Error("Could not determine values for query");
|
||||||
}
|
}
|
||||||
|
|
||||||
let [_, valueList] = detailsMatch;
|
let [_, valueList] = detailsMatch;
|
||||||
|
|
||||||
return valueList.split(", ");
|
return valueList.split(", ");
|
||||||
};
|
};
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Promise = require("bluebird");
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: function createCheckConstraintViolationTable(knex, errorHandler) {
|
up: function createCheckConstraintViolationTable(knex, errorHandler) {
|
||||||
return knex.schema.createTable("check_constraint_violation", (table) => {
|
return knex.schema.createTable("check_constraint_violation", (table) => {
|
||||||
table.increments("id");
|
table.increments("id");
|
||||||
table.enum("number_value", ["one", "two", "three"]);
|
table.enum("number_value", ["one", "two", "three"]);
|
||||||
table.text("name");
|
table.text("name");
|
||||||
}).catch(errorHandler);
|
}).catch(errorHandler);
|
||||||
},
|
},
|
||||||
down: function dropCheckConstraintViolationTable(knex, errorHandler) {
|
down: function dropCheckConstraintViolationTable(knex, errorHandler) {
|
||||||
return knex.schema.dropTable("check_constraint_violation").catch(errorHandler);
|
return knex.schema.dropTable("check_constraint_violation").catch(errorHandler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: function createUniqueConstraintViolationTable(knex, errorHandler) {
|
up: function createUniqueConstraintViolationTable(knex, errorHandler) {
|
||||||
return knex.schema.createTable("composite_unique_constraint_violation", (table) => {
|
return knex.schema.createTable("composite_unique_constraint_violation", (table) => {
|
||||||
table.increments("id");
|
table.increments("id");
|
||||||
table.text("email");
|
table.text("email");
|
||||||
table.text("username");
|
table.text("username");
|
||||||
table.text("name");
|
table.text("name");
|
||||||
table.unique(["email", "username"]);
|
table.unique(["email", "username"]);
|
||||||
}).catch(errorHandler);
|
}).catch(errorHandler);
|
||||||
},
|
},
|
||||||
down: function dropUniqueConstraintViolationTable(knex, errorHandler) {
|
down: function dropUniqueConstraintViolationTable(knex, errorHandler) {
|
||||||
return knex.schema.dropTable("composite_unique_constraint_violation").catch(errorHandler);
|
return knex.schema.dropTable("composite_unique_constraint_violation").catch(errorHandler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: function createInvalidTypeTable(knex, errorHandler) {
|
up: function createInvalidTypeTable(knex, errorHandler) {
|
||||||
return knex.schema.createTable("invalid_type", (table) => {
|
return knex.schema.createTable("invalid_type", (table) => {
|
||||||
table.increments("id");
|
table.increments("id");
|
||||||
table.integer("age");
|
table.integer("age");
|
||||||
table.text("name");
|
table.text("name");
|
||||||
table.boolean("active");
|
table.boolean("active");
|
||||||
}).catch(errorHandler);
|
}).catch(errorHandler);
|
||||||
},
|
},
|
||||||
down: function dropInvalidTypeTable(knex, errorHandler) {
|
down: function dropInvalidTypeTable(knex, errorHandler) {
|
||||||
return knex.schema.dropTable("invalid_type").catch(errorHandler);
|
return knex.schema.dropTable("invalid_type").catch(errorHandler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: function createNotNullConstraintViolationTable(knex, errorHandler) {
|
up: function createNotNullConstraintViolationTable(knex, errorHandler) {
|
||||||
return knex.schema.createTable("not_null_violation", (table) => {
|
return knex.schema.createTable("not_null_violation", (table) => {
|
||||||
table.increments("id");
|
table.increments("id");
|
||||||
table.text("email").notNull();
|
table.text("email").notNull();
|
||||||
table.text("name");
|
table.text("name");
|
||||||
}).catch(errorHandler);
|
}).catch(errorHandler);
|
||||||
},
|
},
|
||||||
down: function dropNotNullConstraintViolationTable(knex, errorHandler) {
|
down: function dropNotNullConstraintViolationTable(knex, errorHandler) {
|
||||||
return knex.schema.dropTable("not_null_violation").catch(errorHandler);
|
return knex.schema.dropTable("not_null_violation").catch(errorHandler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
up: function createUniqueConstraintViolationTable(knex, errorHandler) {
|
up: function createUniqueConstraintViolationTable(knex, errorHandler) {
|
||||||
return knex.schema.createTable("unique_constraint_violation", (table) => {
|
return knex.schema.createTable("unique_constraint_violation", (table) => {
|
||||||
table.increments("id");
|
table.increments("id");
|
||||||
table.text("email").unique();
|
table.text("email").unique();
|
||||||
table.text("name");
|
table.text("name");
|
||||||
}).catch(errorHandler);
|
}).catch(errorHandler);
|
||||||
},
|
},
|
||||||
down: function dropUniqueConstraintViolationTable(knex, errorHandler) {
|
down: function dropUniqueConstraintViolationTable(knex, errorHandler) {
|
||||||
return knex.schema.dropTable("unique_constraint_violation").catch(errorHandler);
|
return knex.schema.dropTable("unique_constraint_violation").catch(errorHandler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = function attemptCheckConstraintViolation(knex) {
|
module.exports = function attemptCheckConstraintViolation(knex) {
|
||||||
return knex("check_constraint_violation").insert([{
|
return knex("check_constraint_violation").insert([{
|
||||||
number_value: "one",
|
number_value: "one",
|
||||||
name: "Joe"
|
name: "Joe"
|
||||||
}, {
|
}, {
|
||||||
number_value: "four",
|
number_value: "four",
|
||||||
name: "Jane"
|
name: "Jane"
|
||||||
}]).returning("*");
|
}]).returning("*");
|
||||||
};
|
};
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = function attemptCompositeUniqueConstraintViolation(knex) {
|
module.exports = function attemptCompositeUniqueConstraintViolation(knex) {
|
||||||
return knex("composite_unique_constraint_violation").insert([{
|
return knex("composite_unique_constraint_violation").insert([{
|
||||||
email: "foo@bar.com",
|
email: "foo@bar.com",
|
||||||
username: "foo",
|
username: "foo",
|
||||||
name: "Joe"
|
name: "Joe"
|
||||||
}, {
|
}, {
|
||||||
email: "baz@qux.com",
|
email: "baz@qux.com",
|
||||||
username: "bar",
|
username: "bar",
|
||||||
name: "Jane"
|
name: "Jane"
|
||||||
}, {
|
}, {
|
||||||
email: "foo@bar.com",
|
email: "foo@bar.com",
|
||||||
username: "baz",
|
username: "baz",
|
||||||
name: "Pete"
|
name: "Pete"
|
||||||
}, {
|
}, {
|
||||||
email: "foo@bar.com",
|
email: "foo@bar.com",
|
||||||
username: "foo",
|
username: "foo",
|
||||||
name: "Jill"
|
name: "Jill"
|
||||||
}]).returning("*");
|
}]).returning("*");
|
||||||
};
|
};
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = function attemptEnumViolation(knex) {
|
module.exports = function attemptEnumViolation(knex) {
|
||||||
return knex("enum_violation").insert([{
|
return knex("enum_violation").insert([{
|
||||||
number_value: "one",
|
number_value: "one",
|
||||||
name: "Joe"
|
name: "Joe"
|
||||||
}, {
|
}, {
|
||||||
number_value: "four",
|
number_value: "four",
|
||||||
name: "Jane"
|
name: "Jane"
|
||||||
}]).returning("*");
|
}]).returning("*");
|
||||||
};
|
};
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = function attemptInvalidTypeBooleanInverse(knex) {
|
module.exports = function attemptInvalidTypeBooleanInverse(knex) {
|
||||||
return knex("invalid_type").insert([{
|
return knex("invalid_type").insert([{
|
||||||
name: "Joe",
|
name: "Joe",
|
||||||
age: 29,
|
age: 29,
|
||||||
active: true
|
active: true
|
||||||
}, {
|
}, {
|
||||||
name: "Jane",
|
name: "Jane",
|
||||||
age: 42,
|
age: 42,
|
||||||
active: true
|
active: true
|
||||||
}, {
|
}, {
|
||||||
name: true,
|
name: true,
|
||||||
age: 24,
|
age: 24,
|
||||||
active: false
|
active: false
|
||||||
}]).returning("*");
|
}]).returning("*");
|
||||||
};
|
};
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = function attemptInvalidTypeBoolean(knex) {
|
module.exports = function attemptInvalidTypeBoolean(knex) {
|
||||||
return knex("invalid_type").insert([{
|
return knex("invalid_type").insert([{
|
||||||
name: "Joe",
|
name: "Joe",
|
||||||
age: 29,
|
age: 29,
|
||||||
active: true
|
active: true
|
||||||
}, {
|
}, {
|
||||||
name: "Jane",
|
name: "Jane",
|
||||||
age: 42,
|
age: 42,
|
||||||
active: true
|
active: true
|
||||||
}, {
|
}, {
|
||||||
name: "Pete",
|
name: "Pete",
|
||||||
age: 24,
|
age: 24,
|
||||||
active: "foo bar"
|
active: "foo bar"
|
||||||
}]).returning("*");
|
}]).returning("*");
|
||||||
};
|
};
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = function attemptInvalidTypeInteger(knex) {
|
module.exports = function attemptInvalidTypeInteger(knex) {
|
||||||
return knex("invalid_type").insert([{
|
return knex("invalid_type").insert([{
|
||||||
name: "Joe",
|
name: "Joe",
|
||||||
age: 29,
|
age: 29,
|
||||||
active: true
|
active: true
|
||||||
}, {
|
}, {
|
||||||
name: "Jane",
|
name: "Jane",
|
||||||
age: 42,
|
age: 42,
|
||||||
active: true
|
active: true
|
||||||
}, {
|
}, {
|
||||||
name: "Pete",
|
name: "Pete",
|
||||||
age: "twenty-four",
|
age: "twenty-four",
|
||||||
active: false
|
active: false
|
||||||
}]).returning("*");
|
}]).returning("*");
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = function attemptNotNullConstraintViolation(knex) {
|
module.exports = function attemptNotNullConstraintViolation(knex) {
|
||||||
return knex("not_null_violation").insert([{
|
return knex("not_null_violation").insert([{
|
||||||
email: "foo@bar.com",
|
email: "foo@bar.com",
|
||||||
name: "Joe"
|
name: "Joe"
|
||||||
}, {
|
}, {
|
||||||
email: "baz@qux.com"
|
email: "baz@qux.com"
|
||||||
}, {
|
}, {
|
||||||
name: "Pete"
|
name: "Pete"
|
||||||
}]).returning("*");
|
}]).returning("*");
|
||||||
};
|
};
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = function attemptUndefinedColumn(knex) {
|
module.exports = function attemptUndefinedColumn(knex) {
|
||||||
return knex("invalid_type").insert([{
|
return knex("invalid_type").insert([{
|
||||||
name: "Joe",
|
name: "Joe",
|
||||||
age: 29,
|
age: 29,
|
||||||
active: true,
|
active: true,
|
||||||
nonexistentColumn: "Hello!"
|
nonexistentColumn: "Hello!"
|
||||||
}]).returning("*");
|
}]).returning("*");
|
||||||
};
|
};
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
module.exports = function attemptUniqueConstraintViolation(knex) {
|
module.exports = function attemptUniqueConstraintViolation(knex) {
|
||||||
return knex("unique_constraint_violation").insert([{
|
return knex("unique_constraint_violation").insert([{
|
||||||
email: "foo@bar.com",
|
email: "foo@bar.com",
|
||||||
name: "Joe"
|
name: "Joe"
|
||||||
}, {
|
}, {
|
||||||
email: "baz@qux.com",
|
email: "baz@qux.com",
|
||||||
name: "Jane"
|
name: "Jane"
|
||||||
}, {
|
}, {
|
||||||
email: "foo@bar.com",
|
email: "foo@bar.com",
|
||||||
name: "Pete"
|
name: "Pete"
|
||||||
}]).returning("*");
|
}]).returning("*");
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue