import { Prisma } from '../../generated/prisma'; /** What of an error may go into the log. */ export interface LoggableError { message: string; stack: string | undefined; } const PRISMA_ERRORS = [ Prisma.PrismaClientKnownRequestError, Prisma.PrismaClientUnknownRequestError, Prisma.PrismaClientRustPanicError, Prisma.PrismaClientInitializationError, Prisma.PrismaClientValidationError, ]; function isPrismaError(error: unknown): error is Error { return PRISMA_ERRORS.some((type) => error instanceof type); } function modelName(meta: Record | undefined): string | null { return typeof meta?.modelName === 'string' ? meta.modelName : null; } /** * Prisma error messages quote the failing query - titles, descriptions, * names, i.e. personal data - and so does the stack, whose first line is * the message. A Prisma error is therefore logged by name, error code and * model only. Any other error keeps message and stack for diagnosis. */ export function loggableError(error: unknown): LoggableError { if (error instanceof Prisma.PrismaClientKnownRequestError) { const model = modelName(error.meta); return { message: `${error.name} ${error.code}${model ? ` (${model})` : ''}`, stack: undefined, }; } if (isPrismaError(error)) { return { message: error.name, stack: undefined }; } if (error instanceof Error) { return { message: error.message, stack: error.stack }; } return { message: String(error), stack: undefined }; }