errorInfo = ['23505', 7, 'Unique violation']; throw new QueryException('pgsql', 'INSERT INTO users ...', [], $pdoException); }); /* @phpstan-ignore-next-line method.notFound */ $this->getJson('/_test/boom-23505'); // Constraint violation โ†’ warning channel, with sqlstate context /* @phpstan-ignore-next-line staticMethod.notFound */ Log::shouldHaveReceived('warning') ->withArgs(function ($message, $context) { return $message === 'db.constraint_violation' && ($context['sqlstate'] ?? '') === '23505'; }) ->atLeast()->once(); // Default behaviour (full error log) is NOT called for constraint violations /* @phpstan-ignore-next-line staticMethod.notFound */ Log::shouldNotHaveReceived('error', [ Mockery::on(fn ($msg) => $msg === 'db.query_exception'), ]); }); it('still logs non-constraint QueryException (SQLSTATE 42P01) as ERROR with full SQL', function () { Log::spy(); Route::get('/_test/boom-42P01', function () { $pdoException = new PDOException('SQLSTATE[42P01]: relation "missing_table" does not exist'); $pdoException->errorInfo = ['42P01', 7, 'Undefined table']; throw new QueryException('pgsql', 'SELECT * FROM missing_table', [], $pdoException); }); /* @phpstan-ignore-next-line method.notFound */ $this->getJson('/_test/boom-42P01'); // Non-constraint โ†’ default error logging preserved /* @phpstan-ignore-next-line staticMethod.notFound */ Log::shouldHaveReceived('error') ->withArgs(function ($message, $context) { return $message === 'db.query_exception' && isset($context['sql']); }) ->atLeast()->once(); }); it('logs constraint violation (SQLSTATE 23514) for check_constraint as WARNING', function () { Log::spy(); Route::get('/_test/boom-23514', function () { $pdoException = new PDOException('SQLSTATE[23514]: Check violation: new row for relation "supplier_projects" violates check constraint "chk_supplier_projects_b1_not_for_sms"'); $pdoException->errorInfo = ['23514', 7, 'Check violation']; throw new QueryException('pgsql', 'INSERT INTO supplier_projects ...', [], $pdoException); }); /* @phpstan-ignore-next-line method.notFound */ $this->getJson('/_test/boom-23514'); /* @phpstan-ignore-next-line staticMethod.notFound */ Log::shouldHaveReceived('warning') ->withArgs(function ($message, $context) { return $message === 'db.constraint_violation' && ($context['sqlstate'] ?? '') === '23514'; }) ->atLeast()->once(); });