Mercurial > pub > Impl
diff Lib/IMPL/Exception.pm @ 0:03e58a454b20
Создан репозитарий
author | Sergey |
---|---|
date | Tue, 14 Jul 2009 12:54:37 +0400 |
parents | |
children | 16ada169ca75 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Lib/IMPL/Exception.pm Tue Jul 14 12:54:37 2009 +0400 @@ -0,0 +1,113 @@ +package IMPL::Exception; +use strict; +use overload + '""' => \&ToString, + 'fallback' => 1; +use Carp qw(longmess shortmess); +use Scalar::Util qw(refaddr); + +BEGIN { + require Error; +} + +use base qw(IMPL::Object::Accessor Error); + +BEGIN { + __PACKAGE__->mk_accessors( qw(Message Args CallStack Source) ); +} + +sub indent { + my ($str,$level) = @_; + $level ||= 0; + $str = '' unless defined $str; + join ("\n", map( "\t"x$level.$_ , split(/\n/,$str) ) ); +} + +sub new { + my $class = shift; + $class = ref $class || $class; + + my $this = $class->Error::new() or die "Failed to create an exception"; + + $this->callCTOR(@_); + $this->{-text} = $this->Message; + + local $Carp::CarpLevel = 0; + + $this->CallStack(longmess); + $this->Source(shortmess); + + return $this; +} + +sub CTOR { + my ($this,$message,@args) = @_; + $this->Message($message || ''); + die new IMPL::Exception("Fatal erorr: cyclic structure in the exceptions were detected, do not use \$\@ while throwing the exception!") if grep ref $_ ? refaddr($this) == refaddr($_) : 0 , @args; + $this->Args([map defined $_ ? $_ : 'undef', @args]); +} + +sub save { + my ($this,$ctx) = @_; + + $ctx->AddVar(Message => $this->Message) if $this->Message; + $ctx->AddVar(Args => $this->Args) if @{$this->Args}; + $ctx->AddVar(Source => $this->Source); + $ctx->AddVar(CallStack => $this->CallStack); +} + +sub restore { + my ($class,$data,$instance) = @_; + + my %args = @$data; + + if ($instance) { + $instance->callCTOR($args{Message},@{$args{Args}}); + } else { + $instance = $class->new($args{Message},@{$args{Args}}); + } + + $instance->Source($args{Source}); + $instance->CallStack($args{CallStack}); + + return $instance; +} + +sub ToString { + my $this = shift; + + $this->toString(); +} + +sub toString { + my ($this,$notrace) = @_; + $this->Message . join("\n",'',map { my $s = $_; local $_; indent("$s",1) } @{$this->Args} ) . ( $notrace ? '' : "\n" . $this->CallStack); +} + +package IMPL::InvalidOperationException; +our @ISA = qw(IMPL::Exception); +__PACKAGE__->PassThroughArgs; + +package IMPL::InvalidArgumentException; +our @ISA = qw(IMPL::Exception); +__PACKAGE__->PassThroughArgs; + +package IMPL::DuplicateException; +our @ISA = qw(IMPL::Exception); +__PACKAGE__->PassThroughArgs; + +package IMPL::NotImplementedException; +our @ISA = qw(IMPL::Exception); +__PACKAGE__->PassThroughArgs; + +package Exception; +our @ISA = qw(IMPL::Exception); +__PACKAGE__->PassThroughArgs; + +package IMPL::DeprecatedException; +our @ISA = qw(IMPL::Exception); +our %CTOR = ( + 'IMPL::Exception' => sub { @_ ? @_ : "The method is deprecated" } +); + +1;