'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) }); } };