The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Neo4j::Error - Common Neo4j exception representations

VERSION

version 0.02

SYNOPSIS

 # Consumer:
 QUERY: {
   $result = $dbh->run_neo4j($query);
   if ($result isa Neo4j::Error) {
     redo QUERY if $e->is_retryable && ++$counter < 3;
     printf "Neo4j [%s] error %s: %s",
       $e->source, $e->code, $e->as_string;
   }
 }
 
 # Producer:
 $server_error = Neo4j::Error->new( Server => {
   code      => 'Neo.ClientError.Statement.SyntaxError',
   message   => 'Parsing the Cypher query failed',
 });
 $http_error   = Neo4j::Error->new( Network => {
   code      => '401',
   message   => 'Unauthorized',
 });
 $intern_error = Neo4j::Error->new( Internal => {
   as_string => 'JSON decoding failure',
 });
 $usage_error  = Neo4j::Error->new( Usage => {
   as_string => 'Calling get() with two args is not allowed',
 });

DESCRIPTION

Common Neo4j exception representations.

Each instance represents an error (or warning) that was issued by the Neo4j graph database server, networking library, Neo4j Perl driver or similar source. Instances are meant to be immutable.

Instances are not necessarily meant to be thrown as exceptions with die. They might be used for error reporting through other means.

METHODS

Neo4j::Error implements the following methods.

as_string

 $text = $error->as_string;

Return a human-readable error message that also includes the error code and possibly further information. Basically something you would expect to be passed to die.

If as_string has not been provided to new(), this software tries to auto-generate something suitable.

category

 $string = $error->category;

The Neo4j "subtype" of this error, parsed from the Neo4j status code. Formerly known as "category". One of: Cluster, Database, Fabric, General, LegacyIndex, Procedure, Request, Routing, Schema, Security, Statement, Transaction.

For errors that don't originate on the Neo4j server, this method returns the empty string.

classification

 $string = $error->classification;

The Neo4j "type" of this error, parsed from the Neo4j status code. Formerly known as "classification". One of: ClientError, ClientNotification, TransientError, DatabaseError.

For errors that don't originate on the Neo4j server, this method returns the empty string.

code

 $code = $error->code;

Return a machine-readable error identification. The kind of code varies by the source of this error. For errors that originate on the Neo4j server, the Neo4j status code string is passed through. For other error sources, the code may be an error number or other identifier.

Note that some error conditions are not associated with a machine-readable code. For such errors, this method returns the empty string.

is_retryable

 $boolean = $error->is_retryable;

Whether the error is of a type that suggests it would be safe and reasonable to retry the original request without alteration (assuming it is idempotent). Examples of such errors might be deadlocks or memory issues.

In particular, this method returns true for the following errors:

  • Neo4j errors with the classification TransientError

  • currently, all network errors (liable to change)

message

 $text = $error->message;

Return a human-readable error message. Basically something you would expect to be passed to die, except it should not include the error code and should also be reasonably short.

If no message is available, this method returns the empty string.

raw

 $data = $error->raw;

Return raw data if available, which might potentially contain additional information about the error. For example, the body content of an HTTP response or the "failure details" hashref of a Neo4j::Bolt::ResultStream.

If no raw data is available, this method returns undef.

 $next_error = $error->related;
 
 # Traverse the linked list
 do { say $error->as_string } while $error = $error->related;

Return the next related error.

When multiple errors occur at the same time, they may be made available in the form of a singly-linked list. This method provides the next error in that list. This is conceptually similar to the "caused by" relationship known from exception systems in some other languages such as Java, but different in that the type of the relationship is not defined. In general, the first error object you receive directly from your database driver should represent the primary error condition, with additional supporting information made available by any related errors. Consequently, it should in general be safe to ignore any related errors altogether; however, this depends on the database driver's behaviour and is not necessarily guaranteed.

If there is no next related error, this method returns undef.

source

 $source = $error->source;

The original source of this error. One of: Server, Network, Internal, Usage.

See "ERROR SOURCES" below.

title

 $string = $error->title;

The Neo4j "name" of this error, parsed from the Neo4j status code. Formerly known as "title".

For errors that don't originate on the Neo4j server, this method returns the empty string.

trace

 $stack_trace = $error->trace;
 print $stack_trace->as_string;

Return a stack trace in the form of a Devel::StackTrace object. The trace begins at the point where the error object was created.

CONSTRUCTORS

See also: "BUGS AND LIMITATIONS"

Neo4j::Error implements the following constructor methods.

new

 $e = Neo4j::Error->new( $source => \%error_info );
 
 # Hashref optional for pure string error messages
 $e = Neo4j::Error->new( Internal => {as_string => $error_string} );
 $e = Neo4j::Error->new( Internal => "$error_string" );

Construct a new Neo4j::Error object.

The new() method expects to be given an error source and a hashref with further information about the error the new object is meant to represent. Hash entries should have the same names as methods in this module. Not all hash entries might be used. Any unneeded hash entries are silently ignored.

When as_string would be the only hash entry, the hashref may optionally be replaced by a string.

If the optional trace hash entry is present, its contents are interpreted as Devel::StackTrace constructor parameters.

As decoded Neo4j Jolt/JSON error events are simply hashrefs with two entries code and message, they can be passed to new() as-is. This software will properly handle both Jolt formats ("sparse" and "strict").

append_new

 $e = 'Neo4j::Error';
 $e = $e->append_new( ... ) if $error_cond_1;
 $e = $e->append_new( ... ) if $error_cond_2;
 $e = $e->append_new( ... ) if $error_cond_3;
 if (ref $e) {
   # Handle errors in the order they occurred
   do { handle_error $e } while $e = $e->related;
 }

If called as class method, append_new() behaves identically to new().

If called as object method, append_new() traverses the linked list of related errors and appends the newly constructed error to the end of the list. In situations where a variety of error conditions might or might not apply, this constructor provides a way to assemble an error object with any number of related errors using a simple and consistent call syntax.

ERROR SOURCES

See also: "BUGS AND LIMITATIONS"

The source of the error is indicated by the error object's class. It is also available as a string via source().

Reported error sources aren't necessarily indicative of the true error cause, because not every error fits neatly into one single group. For example, an authentication failure (wrong password) might legitimately be reported as coming from any of these sources:

  • Server: Neo4j status Neo.ClientError.Security.Unauthorized

  • Network: HTTP status 401 or Bolt libneo4j-omni -15

  • Internal: Default fallback because the true cause is unclear

  • Usage: Wrong password supplied by user

For an individual Neo4j::Error object, the primary significance of the source is to define the semantics of the error's code().

Server

Represents an error that originates on a Neo4j server. Always has a code in the form of a Neo4j status code, with individual components that can be queried using classification(), category(), and title().

Network

Represents a network protocol or network library having signalled an error condition. The error code is either defined by the protocol (as is the case for HTTP) or by the networking library (for example libneo4j-omni, used by Neo4j::Bolt). The actual cause of the error may or may not be network-related.

Internal

Represents an error condition that originates locally in the software creating the Neo4j::Error object (the database driver). The "internal" source is also used as a default fallback in case the error is not clearly attributable to a more specific source. May or may not have an error code.

Note that depending on the cause of the error, your software might just die ordinarily with a string message instead of reporting the error using this class.

Usage

Represents a case of the user supplying the wrong arguments to a method or using an object in an illegal state. Usually has no error code. Note that your software might well just die ordinarily with a string message instead of reporting the error using this class.

BUGS AND LIMITATIONS

This distribution is new and still somewhat experimental. Aspects of the interface that are still evolving are primarily the constructors and the semantics of "sources".

SEE ALSO

AUTHOR

Arne Johannessen (AJNN)

COPYRIGHT AND LICENSE

This software is Copyright (c) 2023 by Arne Johannessen.

This is free software; you can redistribute it and/or modify it under the terms of the Artistic License 2.0 or (at your option) the same terms as the Perl 5 programming language system itself.