NAME
DBIO::Exception::Server - A refusal by the database server, with its SQLSTATE
VERSION
version 0.900004
DESCRIPTION
The error an async transport fails a Future with when the server refused a statement: a unique violation, a deadlock, a serialization failure, a cancelled statement. It is a DBIO::Exception that also carries what the server said in machine-readable form, so a caller tells 40001, 40P01, 23505 and 57014 apart without parsing text -- text that depends on the server's lc_messages.
It stringifies to the message it was built with, exactly the text the Future failed with before a transport made these objects, and compares as that string: $@ =~ /.../, eq and like keep working.
my $f = $storage->insert_async($source, \%row);
$f->catch(sub {
my ($error) = @_;
if (Scalar::Util::blessed($error)
&& $error->isa('DBIO::Exception::Server')
&& ($error->sqlstate // '') eq '23505') {
...
}
});
Core hands such an object on unchanged -- the one the transport failed with, not a copy -- through txn_do_async and pipeline ("WHAT A TRANSPORT FAILS WITH" in DBIO::Future, ADR 0062). Where core puts text in front of it -- a failed BEGIN, COMMIT or ROLLBACK of a transaction -- the caller gets a derived copy of the same class and fields with "context" set, stringifying with that prefix.
The synchronous path raises it too: a statement the DBI handle refused is a DBIO::Exception::Server from DBIO::Storage::DBI, its text the decorated DBI Exception: ... it always was, its sqlstate the handle's state. Every field is undef where the handle gave none.
METHODS
new
my $error = DBIO::Exception::Server->new(
message => qq{ERROR: duplicate key value ...\n},
sqlstate => '23505',
constraint => 'artist_name_key',
table => 'artist',
detail => 'Key (name)=(Duplicate) already exists.',
);
message is required and is the text the object stringifies to; core does not add to it (no caller, no newline). The other fields (context too, which core sets on a derived copy -- see "with_context") are optional and undef when the server did not report them. Unknown arguments are refused.
throw
DBIO::Exception::Server->throw(message => ..., sqlstate => ...);
new and die, for code that raises it synchronously. Takes the arguments of "new"; unlike "throw" in DBIO::Exception it does not decorate the message with the caller.
sqlstate
The five-character SQLSTATE the server reported (23505), or undef.
constraint
The name of the constraint the statement violated, or undef.
table
The name of the table the error concerns, or undef.
detail
The server's detail line (PostgreSQL DETAIL), or undef.
context
What core was doing when it prefixed the message: BEGIN, COMMIT or ROLLBACK for the failure of that step of a transaction, or undef -- the object is the one the server's refusal made, with no step of core's in front of it. It is set on the derived copy core hands the caller, never on the object a transport failed with.
with_context
my $copy = $error->with_context('COMMIT', "COMMIT failed: $error");
A derived copy: same class (a subclass stays itself), sqlstate, constraint, table and detail unchanged, context set, and -- when $message is given -- the text it stringifies to replaced. The original is not touched. Throws a DBIO::Exception for an empty context or a false message.
AUTHOR
DBIO & DBIx::Class Authors
COPYRIGHT AND LICENSE
Copyright (C) 2026 DBIO Authors Portions Copyright (C) 2005-2025 DBIx::Class Authors Based on DBIx::Class, heavily modified.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.