You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

60 lines
1.8 KiB
JavaScript

'use strict';
const { create } = require("error-chain");
const pgErrorCodes = require("pg-error-codes");
const DatabaseError = require("../database-error.js");
const getColumns = require("../get-columns");
const getValues = require("../get-values");
let CheckConstraintViolationError = create("CheckConstraintViolationError", { inheritsFrom: DatabaseError });
let messageRegex = /^(.+) - new row for relation "([^"]+)" violates check constraint "([^"]+)"$/;
module.exports = {
error: CheckConstraintViolationError,
errorName: "CheckConstraintViolationError",
check: function checkType(error) {
return (
// PostgreSQL (via `pg`):
(error.length != null && error.file != null && error.line != null && error.routine != null && error.code === "23514")
);
},
convert: function convertError(error) {
let messageMatch = messageRegex.exec(error.message);
if (messageMatch == null) {
throw new Error("Encountered unknown error format");
}
let [_, query, _table, _constraint] = messageMatch;
let columns = getColumns(query);
let offendingColumn, message;
if (columns != null) {
/* This is the naming convention that Knex uses for .enum() in PostgreSQL */
offendingColumn = columns.find(column => {
return error.constraint === `${error.table}_${column}_check`;
});
message = `Value violates the '${error.constraint}' constraint for the '${offendingColumn}' column in the '${error.table}' table`;
} else {
message = `Value violates the '${error.constraint}' constraint for the '${error.table}' table`;
}
return new CheckConstraintViolationError(message, {
originalError: error,
pgCode: error.code,
code: pgErrorCodes[error.code],
query: query,
schema: error.schema,
table: error.table,
column: offendingColumn,
constraint: error.constraint,
values: getValues(error.detail)
});
}
};