NAME

Venus::Error - Error Class

ABSTRACT

Error Class for Perl 5

SYNOPSIS

package main;

use Venus::Error;

my $error = Venus::Error->new;

# $error->throw;

DESCRIPTION

This package represents a context-aware error (exception object). The default for error verbosity can be controlled via the VENUS_ERROR_VERBOSE environment variable, e.g. a setting of 0 disables stack traces. The default trace-offset can be controlled via the VENUS_ERROR_TRACE_OFFSET environment variable, e.g. a setting of 0 indicates no offset.

ATTRIBUTES

This package has the following attributes:

name

name(string $name) (string)

The name attribute is read-write, accepts string values, and is optional.

Since 0.01

name example 1
# given: synopsis

package main;

my $set_name = $error->name("on.save");

# "on.save"
name example 2
# given: synopsis

# given: example-1 name

package main;

my $get_name = $error->name;

# "on.save"

cause

cause(Venus::Error $error) (Venus::Error)

The cause attribute is read-write, accepts Venus::Error values, and is optional.

Since 4.15

cause example 1
# given: synopsis

package main;

my $set_cause = $error->cause(Venus::Error->new);

# bless(..., "Venus::Error")
cause example 2
# given: synopsis

# given: example-1 cause

package main;

my $get_cause = $error->cause;

# bless(..., "Venus::Error")

context

context(string $context) (string)

The context attribute is read-write, accepts string values, and is optional. Defaults to 'N/A'.

Since 0.01

context example 1
# given: synopsis

package main;

my $set_context = $error->context("main::main");

# "main::main"
context example 2
# given: synopsis

# given: example-1 context

package main;

my $get_context = $error->context;

# "main::main"

message

message(string $message) (string)

The message attribute is read-write, accepts string values, and is optional. Defaults to 'Exception!'.

Since 0.01

message example 1
# given: synopsis

package main;

my $set_message = $error->message("Exception!");

# "Exception!"
message example 2
# given: synopsis

# given: example-1 message

package main;

my $get_message = $error->message;

# "Exception!"

verbose

verbose(number $verbose) (number)

The verbose attribute is read-write, accepts number values, and is optional. Defaults to true.

Since 0.01

verbose example 1
# given: synopsis

package main;

my $set_verbose = $error->verbose(true);

# true
verbose example 2
# given: synopsis

# given: example-1 verbose

package main;

my $get_verbose = $error->verbose;

# true

INHERITS

This package inherits behaviors from:

Venus::Kind::Utility

INTEGRATES

This package integrates behaviors from:

Venus::Role::Explainable

Venus::Role::Encaseable

METHODS

This package provides the following methods:

arguments

arguments(number $index) (any)

The arguments method returns the stashed arguments under "captured", or a specific argument if an index is provided.

Since 2.55

arguments example 1
# given: synopsis

my $arguments = $error->arguments;

# undef
arguments example 2
package main;

use Venus::Error;

my $error = Venus::Error->new->capture(1..4);

my $arguments = $error->arguments;

# [1..4]
arguments example 3
package main;

use Venus::Error;

my $error = Venus::Error->new->capture(1..4);

my $arguments = $error->arguments(0);

# 1

as

as(string $name) (Venus::Error)

The as method returns an error object using the return value(s) of the "as" method specified, which should be defined as "as_${name}", which will be called automatically by this method. If no "as_${name}" method exists, this method will set the "name" attribute to the value provided.

Since 1.02

as example 1
package System::Error;

use Venus::Class;

base 'Venus::Error';

sub as_auth_error {
  my ($self) = @_;

  return $self->do('message', 'auth_error');
}

sub as_role_error {
  my ($self) = @_;

  return $self->do('message', 'role_error');
}

sub is_auth_error {
  my ($self) = @_;

  return $self->message eq 'auth_error';
}

sub is_role_error {
  my ($self) = @_;

  return $self->message eq 'role_error';
}

package main;

my $error = System::Error->new->as('auth_error');

$error->throw;

# Exception! (isa Venus::Error)
as example 2
package System::Error;

use Venus::Class;

base 'Venus::Error';

sub as_auth_error {
  my ($self) = @_;

  return $self->do('message', 'auth_error');
}

sub as_role_error {
  my ($self) = @_;

  return $self->do('message', 'role_error');
}

sub is_auth_error {
  my ($self) = @_;

  return $self->message eq 'auth_error';
}

sub is_role_error {
  my ($self) = @_;

  return $self->message eq 'role_error';
}

package main;

my $error = System::Error->new->as('role_error');

$error->throw;

# Exception! (isa Venus::Error)
as example 3
package Virtual::Error;

use Venus::Class;

base 'Venus::Error';

package main;

my $error = Virtual::Error->new->as('on_save_error');

$error->throw;

# name is "on_save_error"

# Exception! (isa Venus::Error)
as example 4
package Virtual::Error;

use Venus::Class;

base 'Venus::Error';

package main;

my $error = Virtual::Error->new->as('on.SAVE.error');

$error->throw;

# name is "on_save_error"

# Exception! (isa Venus::Error)

callframe

callframe(number $index) (any)

The callframe method returns the stashed callframe under "captured", or a specific argument if an index is provided.

Since 2.55

callframe example 1
# given: synopsis

my $callframe = $error->callframe;

# undef
callframe example 2
package main;

use Venus::Error;

my $error = Venus::Error->new->do('offset', 0)->capture;

my $callframe = $error->callframe;

# [...]
callframe example 3
package main;

use Venus::Error;

my $error = Venus::Error->new->do('offset', 0)->capture;

my $package = $error->callframe(0);

# 'main'

capture

capture(any @args) (Venus::Error)

The capture method captures the caller info at the "frame" specified, in the object stash, and returns the invocant.

Since 4.15

capture example 1
# given: synopsis

package main;

$error = $error->capture;

# bless({...}, 'Venus::Error')

captured

captured() (hashref)

The captured method returns the value stashed as "captured".

Since 2.55

captured example 1
# given: synopsis

my $captured = $error->captured;

# undef

copy

copy(Venus::Error $error) (Venus::Error)

The copy method copied the properties of the Venus::Error provided into the invocant and returns the invocant.

Since 4.15

copy example 1
# given: synopsis

package main;

my $oops = Venus::Error->as('on.oops');

my $copy = $error->copy($oops);

# bless({ ... }, 'Venus::Error')

# $error->name;

# "on.oops"
copy example 2
# given: synopsis

package main;

my $oops = Venus::Error->as('on.oops');

$oops->message('Oops, something happened.');

$oops->stash(what => 'Unknown');

my $copy = $error->copy($oops);

# bless({ ... }, 'Venus::Error')

# $error->name;

# "on.oops"

# $error->message;

# "Oops, something happened."

# $error->stash('what');

# "Unknown"

explain

explain() (string)

The explain method returns the error message and is used in stringification operations.

Since 0.01

explain example 1
# given: synopsis;

$error->verbose(0);

my $explain = $error->explain;

# "Exception!" in ...
explain example 2
# given: synopsis;

$error->verbose(1);

my $explain = $error->explain;

# "Exception!" in ...
explain example 3
# given: synopsis;

$error->name('on.save.error');

$error->verbose(1);

my $explain = $error->explain;

# "Exception!" in ...
explain example 4
# given: synopsis;

$error->name('on.save.error');

$error->stash('what', 'Unknown');

$error->verbose(1);

my $explain = $error->explain;

# "Exception!" in ...
explain example 5
package main;

use Venus::Error;

my $step3 = Venus::Error->new(
  name => 'step3',
  message => 'Step 3: Failed',
);

my $step2 = Venus::Error->new(
  name => 'step2',
  message => 'Step 2: Failed',
  cause => $step3,
);

my $step1 = Venus::Error->new(
  name => 'step1',
  message => 'Step 1: Failed',
  cause => $step2,
);

my $explain = $step1->explain;

# "Step 1: Failed" in ...

frame

frame(number $index) (hashref)

The frame method returns the data from caller on the frames captured, and returns a hashref where the keys map to the keys described by "caller" in perlfunc.

Since 1.11

frame example 1
# given: synopsis;

my $frame = $error->frame;

# {
#   'bitmask' => '...',
#   'evaltext' => '...',
#   'filename' => '...',
#   'hasargs' => '...',
#   'hinthash' => '...',
#   'hints' => '...',
#   'is_require' => '...',
#   'line' => '...',
#   'package' => '...',
#   'subroutine' => '...',
#   'wantarray' => '...',
# }
frame example 2
# given: synopsis;

my $frame = $error->frame(1);

# {
#   'bitmask' => '...',
#   'evaltext' => '...',
#   'filename' => '...',
#   'hasargs' => '...',
#   'hinthash' => '...',
#   'hints' => '...',
#   'is_require' => '...',
#   'line' => '...',
#   'package' => '...',
#   'subroutine' => '...',
#   'wantarray' => '...',
# }

frames

frames() (arrayref)

The frames method returns the compiled and stashed stack trace data.

Since 0.01

frames example 1
# given: synopsis;

my $frames = $error->frames;

# [
#   ...
#   [
#     "main",
#     "t/Venus_Error.t",
#     ...
#   ],
# ]

get

get(string @args) (any)

The get method takes one or more attribute and/or method names and returns the result of calling each attribute and/or method. In scalar context returns a single value. In list context results a list of values.

Since 4.15

get example 1
# given: synopsis

package main;

my $get = $error->get('verbose');

# true
get example 2
# given: synopsis

package main;

my $get = $error->get('verbose', 'context');

# true
get example 3
# given: synopsis

package main;

my @get = $error->get('verbose', 'message');

# (true, 'Exception!')

input

input(any @args) (Venus::Error)

The input method captures the arguments provided as associates them with a "callframe" based on the level specified by "offset", in the object stash, and returns the invocant.

Since 4.15

input example 1
# given: synopsis

package main;

$error = $error->input(1..4);

# bless({...}, 'Venus::Error')

is

is(string $name) (boolean)

The is method returns truthy or falsy based on the return value(s) of the "is" method specified, which should be defined as "is_${name}", which will be called automatically by this method. If no "is_${name}" method exists, this method will check if the "name" attribute is equal to the value provided.

Since 1.02

is example 1
package System::Error;

use Venus::Class;

base 'Venus::Error';

sub as_auth_error {
  my ($self) = @_;

  return $self->do('message', 'auth_error');
}

sub as_role_error {
  my ($self) = @_;

  return $self->do('message', 'role_error');
}

sub is_auth_error {
  my ($self) = @_;

  return $self->message eq 'auth_error';
}

sub is_role_error {
  my ($self) = @_;

  return $self->message eq 'role_error';
}

package main;

my $is = System::Error->new->as('auth_error')->is('auth_error');

# 1
is example 2
package System::Error;

use Venus::Class;

base 'Venus::Error';

sub as_auth_error {
  my ($self) = @_;

  return $self->do('message', 'auth_error');
}

sub as_role_error {
  my ($self) = @_;

  return $self->do('message', 'role_error');
}

sub is_auth_error {
  my ($self) = @_;

  return $self->message eq 'auth_error';
}

sub is_role_error {
  my ($self) = @_;

  return $self->message eq 'role_error';
}

package main;

my $is = System::Error->as('auth_error')->is('auth_error');

# 1
is example 3
package System::Error;

use Venus::Class;

base 'Venus::Error';

sub as_auth_error {
  my ($self) = @_;

  return $self->do('message', 'auth_error');
}

sub as_role_error {
  my ($self) = @_;

  return $self->do('message', 'role_error');
}

sub is_auth_error {
  my ($self) = @_;

  return $self->message eq 'auth_error';
}

sub is_role_error {
  my ($self) = @_;

  return $self->message eq 'role_error';
}

package main;

my $is = System::Error->as('auth_error')->is('role_error');

# 0
is example 4
package Virtual::Error;

use Venus::Class;

base 'Venus::Error';

package main;

my $is = Virtual::Error->new->as('on_save_error')->is('on_save_error');

# 1
is example 5
package Virtual::Error;

use Venus::Class;

base 'Venus::Error';

package main;

my $is = Virtual::Error->new->as('on.SAVE.error')->is('on.save.error');

# 1

new

new(any @args) (Venus::Error)

The new method constructs an instance of the package.

Since 4.15

new example 1
package main;

use Venus::Error;

my $new = Venus::Error->new;

# bless(..., "Venus::Error")
new example 2
package main;

use Venus::Error;

my $new = Venus::Error->new('Oops!');

# bless(..., "Venus::Error")
new example 3
package main;

use Venus::Error;

my $new = Venus::Error->new(message => 'Oops!');

# bless(..., "Venus::Error")

of

of(string $name) (boolean)

The of method returns truthy or falsy based on the return value(s) of the "of" method specified, which should be defined as "of_${name}", which will be called automatically by this method. If no "of_${name}" method exists, this method will check if the "name" attribute contains the value provided.

Since 1.11

of example 1
package System::Error;

use Venus::Class;

base 'Venus::Error';

sub as_auth_error {
  my ($self) = @_;

  return $self->do('name', 'auth_error');
}

sub as_role_error {
  my ($self) = @_;

  return $self->do('name', 'role_error');
}

sub is_auth_error {
  my ($self) = @_;

  return $self->name eq 'auth_error';
}

sub is_role_error {
  my ($self) = @_;

  return $self->name eq 'role_error';
}

package main;

my $of = System::Error->as('auth_error')->of('role');

# 0
of example 2
package System::Error;

use Venus::Class;

base 'Venus::Error';

sub as_auth_error {
  my ($self) = @_;

  return $self->do('name', 'auth_error');
}

sub as_role_error {
  my ($self) = @_;

  return $self->do('name', 'role_error');
}

sub is_auth_error {
  my ($self) = @_;

  return $self->name eq 'auth_error';
}

sub is_role_error {
  my ($self) = @_;

  return $self->name eq 'role_error';
}

package main;

my $of = System::Error->as('auth_error')->of('auth');

# 1
of example 3
package System::Error;

use Venus::Class;

base 'Venus::Error';

sub as_auth_error {
  my ($self) = @_;

  return $self->do('name', 'auth_error');
}

sub as_role_error {
  my ($self) = @_;

  return $self->do('name', 'role_error');
}

sub is_auth_error {
  my ($self) = @_;

  return $self->name eq 'auth_error';
}

sub is_role_error {
  my ($self) = @_;

  return $self->name eq 'role_error';
}

package main;

my $of = System::Error->as('auth_error')->of('role_error');

# 0
of example 4
package Virtual::Error;

use Venus::Class;

base 'Venus::Error';

package main;

my $of = Virtual::Error->new->as('on_save_error')->of('on.save');

# 1
of example 5
package Virtual::Error;

use Venus::Class;

base 'Venus::Error';

package main;

my $of = Virtual::Error->new->as('on.SAVE.error')->of('on.save');

# 1

on

on(string $name) (Venus::Error)

The on method sets a "name" for the error in the form of "on.$subroutine.$name" or "on.$name" (if outside of a subroutine) and returns the invocant.

Since 4.15

on example 1
# given: synopsis

package main;

$error = $error->on('handler');

# bless({...}, 'Venus::Error')

# $error->name;

# "on.handler"

output

output(any @args) (Venus::Error)

The output method captures the arguments provided as associates them with a "callframe" based on the level specified by "offset", in the object stash, and returns the invocant.

Since 4.15

output example 1
# given: synopsis

package main;

$error = $error->output(1..4);

# bless({...}, 'Venus::Error')

render

render() (string)

The render method replaces tokens in the message with values from the stash and returns the formatted string. The token style and formatting operation is equivalent to the "render" in Venus::String operation.

Since 3.30

render example 1
# given: synopsis

package main;

$error->message('Signal received: {{signal}}');

$error->stash(signal => 'SIGKILL');

my $render = $error->render;

# "Signal received: SIGKILL"

reset

reset() (Venus::Error)

The reset method resets the "offset" and "verbose" attributes if they're not already set, resets the "context" based on the caller, and rebuilds the stacktrace, then returns the invocant.

Since 4.15

reset example 1
# given: synopsis

package main;

my $reset = $error->reset;

# bless(..., "Venus::Error")
reset example 2
package main;

use Venus::Error;

my $error = Venus::Error->new(offset => 0, verbose => 0);

my $reset = $error->reset;

# bless(..., "Venus::Error")

set

set(any @args) (any)

The set method sets one or more attributes and/or methods on the invocant. This method accepts key/value pairs or a hashref of key/value pairs and returns the invocant.

Since 4.15

set example 1
# given: synopsis

package main;

my $set = $error->set(message => 'Oops!');

# bless(..., "Venus::Error")
set example 2
# given: synopsis

package main;

my $set = $error->set(message => 'Oops!', verbose => false);

# bless(..., "Venus::Error")
set example 3
# given: synopsis

package main;

my $set = $error->set({message => 'Oops!', verbose => false});

# bless(..., "Venus::Error")

stash

stash(string $key, any $value) (any)

The stash method gets and sets ad-hoc data related to the invocant.

Since 4.15

stash example 1
# given: synopsis

package main;

my $stash = $error->stash;

# {}
stash example 2
# given: synopsis

package main;

my $stash = $error->stash('package');

# undef
stash example 3
# given: synopsis

package main;

my $stash = $error->stash('package', 'Example');

# "Example"
stash example 4
# given: synopsis

package main;

$error->stash('package', 'Example');

my $stash = $error->stash('package');

# "Example"
stash example 5
# given: synopsis

package main;

my $stash = $error->stash('package', 'Example', routine => 'execute');

# {
#   package => "Example",
#   routine => "execute",
# }
stash example 6
# given: synopsis

package main;

my $stash = $error->stash({'package', 'Example', routine => 'execute'});

# {
#   package => "Example",
#   routine => "execute",
# }

sysinfo

sysinfo() (Venus::Error)

The sysinfo method calls all the system_* methods and "stashes" the system information.

Since 4.15

sysinfo example 1
# given: synopsis

package main;

my $sysinfo = $error->sysinfo;

# bless(..., "Venus::Error")

# $error->stash('system_name');

# $^O

# $error->stash('system_path');

# /path/to/cwd

# $error->stash('system_perl_path');

# $^X

# $error->stash('system_perl_path');

# $^X

# $error->stash('system_perl_version');

# $^V

# $error->stash('system_process_id');

# $$

# $error->stash('system_script_args');

# [@ARGV]

# $error->stash('system_script_path');

# $0

system_name

system_name(string $value) (Venus::Error)

The system_name method "stashes" a value representing the "system name" and returns the invocant. If no value is provided this method will use $^O as the default.

Since 4.15

system_name example 1
# given: synopsis

package main;

my $system_name = $error->system_name;

# bless(..., "Venus::Error")

# $error->stash('system_name');

# $^O
system_name example 2
# given: synopsis

package main;

my $system_name = $error->system_name($^O);

# bless(..., "Venus::Error")

# $error->stash('system_name');

# $^O

system_path

system_path(string $value) (Venus::Error)

The system_path method "stashes" a value representing the "system_path" and returns the invocant. If no value is provided this method will use Cwd/getcwd as the default.

Since 4.15

system_path example 1
# given: synopsis

package main;

my $system_path = $error->system_path;

# bless(..., "Venus::Error")

# $error->stash('system_path');

# /path/to/cwd
system_path example 2
# given: synopsis

package main;

use Cwd ();

my $system_path = $error->system_path(Cwd->getcwd);

# bless(..., "Venus::Error")

# $error->stash('system_path');

# /path/to/cwd

system_perl_path

system_perl_path(string $value) (Venus::Error)

The system_perl_path method "stashes" a value representing the "system_perl_path" and returns the invocant. If no value is provided this method will use $^X as the default.

Since 4.15

system_perl_path example 1
# given: synopsis

package main;

my $system_perl_path = $error->system_perl_path;

# bless(..., "Venus::Error")

# $error->stash('system_perl_path');

# $^X
system_perl_path example 2
# given: synopsis

package main;

my $system_perl_path = $error->system_perl_path($^X);

# bless(..., "Venus::Error")

# $error->stash('system_perl_path');

# $^X

system_perl_version

system_perl_version(string $value) (Venus::Error)

The system_perl_version method "stashes" a value representing the "system_perl_version" and returns the invocant. If no value is provided this method will use $^V as the default.

Since 4.15

system_perl_version example 1
# given: synopsis

package main;

my $system_perl_version = $error->system_perl_version;

# bless(..., "Venus::Error")

# $error->stash('system_perl_version');

# $^V
system_perl_version example 2
# given: synopsis

package main;

my $system_perl_version = $error->system_perl_version($^V);

# bless(..., "Venus::Error")

# $error->stash('system_perl_version');

# $^V

system_process_id

system_process_id(string $value) (Venus::Error)

The system_process_id method "stashes" a value representing the "system_process_id" and returns the invocant. If no value is provided this method will use $$ as the default.

Since 4.15

system_process_id example 1
# given: synopsis

package main;

my $system_process_id = $error->system_process_id;

# bless(..., "Venus::Error")

# $error->stash('system_process_id');

# $$
system_process_id example 2
# given: synopsis

package main;

my $system_process_id = $error->system_process_id($$);

# bless(..., "Venus::Error")

# $error->stash('system_process_id');

# $$

system_script_args

system_script_args(string $value) (Venus::Error)

The system_script_args method "stashes" a value representing the "system" and returns the invocant. If no value is provided this method will use [@ARGV] as the default.

Since 4.15

system_script_args example 1
# given: synopsis

package main;

my $system_script_args = $error->system_script_args;

# bless(..., "Venus::Error")

# $error->stash('system_script_args');

# [@ARGV]
system_script_args example 2
# given: synopsis

package main;

my $system_script_args = $error->system_script_args(@ARGV);

# bless(..., "Venus::Error")

# $error->stash('system_script_args');

# [@ARGV]

system_script_path

system_script_path(string $value) (Venus::Error)

The system_script_path method "stashes" a value representing the "system_script_path" and returns the invocant. If no value is provided this method will use $0 as the default.

Since 4.15

system_script_path example 1
# given: synopsis

package main;

my $system_script_path = $error->system_script_path;

# bless(..., "Venus::Error")

# $error->stash('system_script_path');

# $0
system_script_path example 2
# given: synopsis

package main;

my $system_script_path = $error->system_script_path($0);

# bless(..., "Venus::Error")

# $error->stash('system_script_path');

# $0

throw

throw(any @data) (Venus::Error)

The throw method throws an error if the invocant is an object, or creates an error object using the arguments provided and throws the created object.

Since 0.01

throw example 1
# given: synopsis;

my $throw = $error->throw;

# bless({ ... }, 'Venus::Error')

trace

trace(number $offset, number $limit) (Venus::Error)

The trace method compiles a stack trace and returns the object. By default it skips the first frame.

Since 0.01

trace example 1
# given: synopsis;

my $trace = $error->trace;

# bless({ ... }, 'Venus::Error')
trace example 2
# given: synopsis;

my $trace = $error->trace(0, 1);

# bless({ ... }, 'Venus::Error')
trace example 3
# given: synopsis;

my $trace = $error->trace(0, 2);

# bless({ ... }, 'Venus::Error')

OPERATORS

This package overloads the following operators:

operation: ("")

This package overloads the "" operator.

example 1

# given: synopsis;

my $result = "$error";

# "Exception!"
operation: (eq)

This package overloads the eq operator.

example 1

# given: synopsis;

my $result = $error eq 'Exception!';

# 1
operation: (ne)

This package overloads the ne operator.

example 1

# given: synopsis;

my $result = $error ne 'exception!';

# 1
operation: (qr)

This package overloads the qr operator.

example 1

# given: synopsis;

my $test = 'Exception!' =~ qr/$error/;

# 1
operation: (~~)

This package overloads the ~~ operator.

example 1

# given: synopsis;

my $result = $error ~~ 'Exception!';

# 1

AUTHORS

Awncorp, awncorp@cpan.org

LICENSE

Copyright (C) 2022, Awncorp, awncorp@cpan.org.

This program is free software, you can redistribute it and/or modify it under the terms of the Apache license version 2.0.