diff --git a/lib/RevBank/Cart.pm b/lib/RevBank/Cart.pm index 752ecfc..55fe046 100644 --- a/lib/RevBank/Cart.pm +++ b/lib/RevBank/Cart.pm @@ -78,9 +78,8 @@ sub size($self) { sub checkout($self, $user) { if ($self->entries('refuse_checkout')) { - warn "Refusing to finalize deficient transaction.\n"; $self->display; - return; + die "Refusing to finalize deficient transaction"; } $user = RevBank::Users::assert_user($user); @@ -108,7 +107,9 @@ sub checkout($self, $user) { $transaction_id = time() - 1300000000; } - RevBank::Plugins::call_hooks("checkout_prepare", $self, $user, $transaction_id); + RevBank::Plugins::call_hooks("checkout_prepare", $self, $user, $transaction_id) + or die "Refusing to finalize after failed checkout_prepare"; + for my $entry (@$entries) { $entry->sanity_check; $entry->user($user) if not $entry->user; @@ -135,11 +136,9 @@ sub checkout($self, $user) { RevBank::Plugins::call_hooks("checkout_done", $self, $user, $transaction_id); sleep 1; # look busy + + $self->empty; }; - - $self->empty; - - return 1; } sub entries($self, $attribute = undef) { diff --git a/lib/RevBank/FileIO.pm b/lib/RevBank/FileIO.pm index 36b53ae..5c11da4 100644 --- a/lib/RevBank/FileIO.pm +++ b/lib/RevBank/FileIO.pm @@ -73,7 +73,7 @@ sub with_lock :prototype(&) ($code) { $rv = $code->() if not $list_context; }; release_lock; - croak $@ =~ s/\n$/, called/r if $@; + croak $@ =~ s/\.?\n$/, rethrown/r if $@; return @rv if $list_context; return $rv if not $list_context; } diff --git a/lib/RevBank/Plugins.pm b/lib/RevBank/Plugins.pm index a113e98..3d288af 100644 --- a/lib/RevBank/Plugins.pm +++ b/lib/RevBank/Plugins.pm @@ -20,17 +20,25 @@ sub _read_file($fn) { sub call_hooks { my $hook = shift; my $method = "hook_$hook"; + my $success = 1; for my $class (@plugins) { if ($class->can($method)) { - my ($rv, @message) = $class->$method(@_); + my ($rv, @message) = eval { $class->$method(@_) }; - if (defined $rv and ref $rv) { + if ($@) { + $success = 0; + call_hooks("plugin_fail", $class->id, "$class->$method died: $@"); + } elsif (defined $rv and ref $rv) { main::abort(@message) if $rv == ABORT; - warn "$class->$method returned an unsupported value.\n"; + + $success = 0; + call_hooks("plugin_fail", $class->id, "$class->$method returned an unsupported value"); } } } + + return $success; }; sub register(@new_plugins) { diff --git a/lib/RevBank/Plugins.pod b/lib/RevBank/Plugins.pod index 8d3868a..6daac5a 100644 --- a/lib/RevBank/Plugins.pod +++ b/lib/RevBank/Plugins.pod @@ -158,7 +158,7 @@ Be careful to avoid infinite loops if you add new stuff. =item hook_checkout_prepare($class, $cart, $user, $transaction_id, @) -Called when the transaction is about to be processed. In this phase, the cart and its entries can still be manipulated. +Called when the transaction is about to be processed. In this phase, the cart and its entries can still be manipulated. If the hook throws an exception, the transaction is aborted. =item hook_checkout($class, $cart, $user, $transaction_id, @) diff --git a/plugins/users b/plugins/users index 1fdf995..34492cf 100644 --- a/plugins/users +++ b/plugins/users @@ -17,7 +17,7 @@ sub command :Tab(list,ls,shame,log,USERS) ($self, $cart, $command, @) { return $self->balance($user) if not $cart->size; - $cart->checkout($user) or return REJECT, "Checkout failed."; + $cart->checkout($user); return ACCEPT; } diff --git a/revbank b/revbank index dba6019..cde8e16 100755 --- a/revbank +++ b/revbank @@ -17,7 +17,7 @@ use RevBank::Global; use RevBank::Messages; use RevBank::Cart; -our $VERSION = "4.2.1"; +our $VERSION = "4.2.2"; our %HELP1 = ( "abort" => "Abort the current transaction", ); @@ -183,18 +183,18 @@ OUTER: for (;;) { ALL_PLUGINS: { PLUGIN: for my $plugin (@plugins) { my ($rv, @rvargs) = eval { $plugin->$method($cart, $word) }; if ($@) { - call_hooks "plugin_fail", $plugin->id, $@; + call_hooks "plugin_fail", $plugin->id, "$method: $@"; abort; } if (not defined $rv) { - call_hooks "plugin_fail", $plugin->id, "No return code"; + call_hooks "plugin_fail", $plugin->id, "$method: No return code"; abort; } if (not ref $rv) { $prompt = $rv; @plugins = $plugin; ($method) = @rvargs; - call_hooks "plugin_fail", $plugin->id, "No method supplied" + call_hooks "plugin_fail", $plugin->id, "$method: No method supplied" if not ref $method; abort "Incomplete command." if $one_off and not @words; @@ -231,11 +231,11 @@ OUTER: for (;;) { } if ($rv == NEXT) { next PLUGIN if $method eq 'command'; - call_hooks "plugin_fail", $plugin->id, "Only 'command' " - . "should ever return NEXT."; + call_hooks "plugin_fail", $plugin->id, "$method: " + . "Only 'command' should ever return NEXT."; abort; } - call_hooks "plugin_fail", $plugin->id, "Invalid return value"; + call_hooks "plugin_fail", $plugin->id, "$method: Invalid return value"; abort; } call_hooks "invalid_input", $cart, $origword, $word, \@allwords;