$self->create_error_confess(@args);
}
+sub _inline_new {
+ my ( $self, @args ) = @_;
+
+ return $self->_inline_create_error_carpmess(@args, longmess => 1);
+}
+
1;
# ABSTRACT: Prefer C<confess>
$self->create_error_croak(@args);
}
+sub _inline_new {
+ my ( $self, @args ) = @_;
+
+ return $self->_inline_create_error_carpmess(@args);
+}
+
1;
# ABSTRACT: Prefer C<croak>
}
}
+sub _inline_new {
+ my ( $self, @args ) = @_;
+
+ return '(do { '
+ . '(defined $ENV{MOOSE_ERROR_STYLE} && $ENV{MOOSE_ERROR_STYLE} eq "croak"'
+ . ' ? ' . $self->_inline_create_error_carpmess(@args)
+ . ' : ' . $self->_inline_create_error_carpmess(@args, longmess => 1)
+ . ')})';
+}
+
sub create_error_croak {
my ( $self, @args ) = @_;
$self->_create_error_carpmess( @args );
}
}
+sub _inline_create_error_carpmess {
+ my ( $self, %args ) = @_;
+
+ my $carp_level = $args{depth} || 0;
+
+ my $create_message = 'Carp::longmess(' . $args{message} . ')';
+
+ if (!$args{longmess}) {
+ $create_message =
+ '($Carp::Verbose '
+ . '? ' . $create_message . ' '
+ . ': Carp::ret_summary('
+ . $carp_level . ', ' . $args{message}
+ . '))';
+ }
+
+ return
+ '(do { '
+ . 'local $Carp::MaxArgNums = 20; '
+ . 'local $Carp::CarpLevel = ($Carp::CarpLevel || 0) + '
+ . $carp_level . '; '
+ . $create_message
+ . '})';
+}
+
1;
# ABSTRACT: L<Carp> based error generation for Moose.
return $self->Moose::Object::does($name);
}
+sub _error_thrower {
+ my $self = shift;
+ require Moose::Meta::Class;
+ ( ref $self && $self->associated_class ) || "Moose::Meta::Class";
+}
+
sub throw_error {
my $self = shift;
- my $class = ( ref $self && $self->associated_class ) || "Moose::Meta::Class";
+ my $inv = $self->_error_thrower;
unshift @_, "message" if @_ % 2 == 1;
unshift @_, attr => $self if ref $self;
- unshift @_, $class;
- my $handler = $class->can("throw_error"); # to avoid incrementing depth by 1
+ unshift @_, $inv;
+ my $handler = $inv->can("throw_error"); # to avoid incrementing depth by 1
goto $handler;
}
sub _inline_throw_error {
my ( $self, $msg, $args ) = @_;
- "\$meta->throw_error($msg" . ($args ? ", $args" : "") . ")"; # FIXME makes deparsing *REALLY* hard
+
+ my $inv = $self->_error_thrower;
+ # XXX ugh
+ $inv = 'Moose::Meta::Class' unless $inv->can('_inline_throw_error');
+
+ # XXX ugh ugh UGH
+ my $class = $self->associated_class;
+ if ($class) {
+ my $class_name = B::perlstring($class->name);
+ my $attr_name = B::perlstring($self->name);
+ $args = 'attr => Class::MOP::class_of(' . $class_name . ')'
+ . '->find_attribute_by_name(' . $attr_name . '), '
+ . (defined $args ? $args : '');
+ }
+
+ return $inv->_inline_throw_error($msg, $args)
}
sub new {
}
sub _inline_throw_error {
- my ( $self, $msg, $args ) = @_;
- "\$meta->throw_error($msg" . ($args ? ", $args" : "") . ")"; # FIXME makes deparsing *REALLY* hard
+ my ( $self, @args ) = @_;
+ $self->_inline_raise_error($self->_inline_create_error(@args));
}
sub raise_error {
die @args;
}
+sub _inline_raise_error {
+ my ( $self, $message ) = @_;
+
+ return (
+ 'die ' . $message . ';',
+ );
+}
+
sub create_error {
my ( $self, @args ) = @_;
);
}
+sub _inline_create_error {
+ my ( $self, $msg, $args ) = @_;
+ # XXX ignore $args for now, nothing currently uses it anyway
+
+ require Carp::Heavy;
+
+ my %args = (
+ metaclass => $self,
+ last_error => $@,
+ message => $msg,
+ );
+
+ my $class = ref $self ? $self->error_class : "Moose::Error::Default";
+
+ Class::MOP::load_class($class);
+
+ # don't check inheritance here - the intention is that the class needs
+ # to provide a non-inherited inlining method, because falling back to
+ # the default inlining method is most likely going to be wrong
+ # yes, this is a huge hack, but so is the entire error system, so.
+ return '$meta->create_error(' . $msg . ', ' . $args . ');'
+ unless $class->meta->has_method('_inline_new');
+
+ $class->_inline_new(
+ # XXX ignore this for now too
+ # Carp::caller_info($args{depth}),
+ %args
+ );
+}
+
1;
# ABSTRACT: The Moose metaclass
sub _error_thrower {
my $self = shift;
+ require Moose::Meta::Class;
( ref $self && $self->associated_metaclass ) || "Moose::Meta::Class";
}
sub _inline_throw_error {
my ( $self, $msg, $args ) = @_;
- "\$meta->throw_error($msg" . ($args ? ", $args" : "") . ")"; # FIXME makes deparsing *REALLY* hard
+
+ my $inv = $self->_error_thrower;
+ # XXX ugh
+ $inv = 'Moose::Meta::Class' unless $inv->can('_inline_throw_error');
+
+ # XXX ugh ugh UGH
+ my $class = $self->associated_metaclass;
+ if ($class) {
+ my $class_name = B::perlstring($class->name);
+ my $meth_name = B::perlstring($self->name);
+ $args = 'method => Class::MOP::class_of(' . $class_name . ')'
+ . '->find_method_by_name(' . $meth_name . '), '
+ . (defined $args ? $args : '');
+ }
+
+ return $inv->_inline_throw_error($msg, $args)
}
1;
# XXX ugh, fix these
$env->{'$attr'} = \$attr
if $attr->has_initializer && $attr->is_lazy;
- $env->{'$meta'} = \$self;
+ # pretty sure this is only going to be closed over if you use a custom
+ # error class at this point, but we should still get rid of this
+ # at some point
+ $env->{'$meta'} = \($self->associated_metaclass);
return $env;
}
} @type_constraints;
return {
- '$meta' => \$self,
((any { defined && $_->has_initializer } @$attrs)
? ('$attrs' => \$attrs)
: ()),
'@type_constraint_bodies' => \@type_constraint_bodies,
( map { defined($_) ? %{ $_->inline_environment } : () }
@type_constraints ),
+ # pretty sure this is only going to be closed over if you use a custom
+ # error class at this point, but we should still get rid of this
+ # at some point
+ '$meta' => \($self->associated_metaclass),
};
}
use Test::More;
use Test::Fatal;
+use Test::Moose;
{
};
}
+with_immutable {
{
my $e = create_error( Foo->new );
ok( !ref( $e->{error} ), "error is a string" );
is_deeply( $e->{error}->data, [ $baz, 4 ], "captured args" );
like( $e->{error}->last_error, qr/Blah/, "last error preserved" );
}
+} 'Foo', 'Bar', 'Baz';
{
package Role::Foo;
cmp_ok(scalar(@lines), '==', 1, "didn't get a stacktrace");
}
+with_immutable {
my $default = Quux::Default->new;
my $croak = Quux::Croak->new;
my $confess = Quux::Confess->new;
stacktrace_not_ok { $croak->bar };
stacktrace_ok { $confess->bar };
}
+} 'Quux::Default', 'Quux::Croak', 'Quux::Confess';
done_testing;