Skip to content

Commit

Permalink
Merge branch 'exception-example'
Browse files Browse the repository at this point in the history
  • Loading branch information
genehack committed Feb 24, 2015
2 parents 28d3408 + 63b92b1 commit 77941cc
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 11 deletions.
72 changes: 67 additions & 5 deletions README.md
Expand Up @@ -96,21 +96,83 @@ yourself before passing it to `Git::Wrapper` methods.
## Error handling

If a git command exits nonzero, a `Git::Wrapper::Exception` object will be
thrown (via `die()`). These objects have three useful methods:
thrown (via `die`) and may be capture via `eval` or [Try::Tiny](https://metacpan.org/pod/Try::Tiny), for
example.

The error object has three useful methods:

- error

error message
Returns the full error message reported by the resulting git command sent to
`STDERR`. This method should not be used as a success/failure check, as `git`
will sometimes produce output on STDERR when a command is successful.

- output

normal output, as a single string
Returns the full output generated by the git command that is sent to `STDOUT`.
This method should not be used as a success/failure check, as `git` will
frequently not have any output with a successful command.

- status

the exit status
Returns the non-zero exit code reported by git on error

### Using `eval`

my $git = Git::Wrapper->new('/path/to/my/repo');
my $ok = eval {
# equivalent to, "git --non-existent-option=1" on the commandline
$git->status({ "non-existent-option"=>1 });
1;
};
if ($@ and ref $@ eq q{Git::Wrapper::Exception}) {
# print STERR from erroneous git command
print $@->error;

# print STOUT from git command
print $@->output;
# print non-zero exist status of git processo
print $@->status;

# quotes are overloaded, so:
print "$@"; # equivalent to $@->error
}

### Using Try::Tiny

use Try::Tiny
my $git = Git::Wrapper->new('/path/to/my/repo');

try {
# equivalent to, "git --non-existent-option=1" on the commandline
$git->status({ "non-existent-option"=>1 });
}
catch {
# print STERR from erroneous git command
print $_->error;
# print STOUT from git command
print $_->output;

# print non-zero exist status of git processo
print $_->status;

# quotes are overloaded, so:
print "$_"; # equivalent to $_->error
}

## Error throwing

A new error object may be generated and thrown as follows:

These exception objects stringify to the error message.
die Git::Wrapper::Exception->new(
output => \@out, # STDOUT
error => \@err, # STERR
status => $? >> 8, # git process exist status
);

# METHODS

Expand Down
68 changes: 63 additions & 5 deletions lib/Git/Wrapper.pm
Expand Up @@ -469,25 +469,83 @@ yourself before passing it to C<Git::Wrapper> methods.
=head2 Error handling
If a git command exits nonzero, a C<Git::Wrapper::Exception> object will be
thrown (via C<die()>). These objects have three useful methods:
thrown (via C<die>) and may be capture via C<eval> or L<Try::Tiny>, for
example.
The error object has three useful methods:
=over
=item * error
error message
Returns the full error message reported by the resulting git command sent to
C<STDERR>. This method should not be used as a success/failure check, as
C<git> will sometimes produce output on STDERR when a command is successful.
=item * output
normal output, as a single string
Returns the full output generated by the git command that is sent to
C<STDOUT>. This method should not be used as a success/failure check, as
C<git> will frequently not have any output with a successful command.
=item * status
the exit status
Returns the non-zero exit code reported by git on error
=back
These exception objects stringify to the error message.
=head3 Using Try::Tiny
L<Try::Tiny> is the recommended way to catch exception objects thrown by
L<Git::Wrapper>.
use Try::Tiny
my $git = Git::Wrapper->new('/path/to/my/repo');
try {
# equivalent to, "git --non-existent-option=1" on the commandline
$git->status({ "non-existent-option"=>1 });
}
catch {
# print STERR from erroneous git command
print $_->error;
# print STOUT from git command
print $_->output;
# print non-zero exist status of git processo
print $_->status;
# quotes are overloaded, so:
print "$_"; # equivalent to $_->error
};
=head3 Using C<eval>
If for some reason you are unable to use L<Try::Tiny>, it is also possible to use the C<eval> function to catch exception objects. B<THIS IS NOT RECOMMENDED!>
my $git = Git::Wrapper->new('/path/to/my/repo');
my $ok = eval {
# equivalent to, "git --non-existent-option=1" on the commandline
$git->status({ "non-existent-option"=>1 });
1;
};
if ($@ and ref $@ eq q{Git::Wrapper::Exception}) {
# print STERR from erroneous git command
print $@->error;
# print STOUT from git command
print $@->output;
# print non-zero exist status of git processo
print $@->status;
# quotes are overloaded, so:
print "$@"; # equivalent to $@->error
}
=head1 METHODS
Expand Down
25 changes: 24 additions & 1 deletion lib/Git/Wrapper/Exception.pm
Expand Up @@ -20,25 +20,48 @@ sub _stringify {
}

sub output { join "", map { "$_\n" } @{ shift->{output} } }

sub error { join "", map { "$_\n" } @{ shift->{error} } }

sub status { shift->{status} }

1;

=head1 SYNOPSIS
A new error object may be generated and thrown as follows:
die Git::Wrapper::Exception->new(
output => \@out, # STDOUT
error => \@err, # STERR
status => $? >> 8, # git process exist status
);
=head1 METHODS
=head2 new
The standard constuctor for this class.
=head2 error
=head2 new
Returns the full error message reported by the resulting git command sent to
C<STDERR>.
=head2 output
Returns the full output generated by the git command that is sent to C<STDOUT>.
=head2 status
Returns the non-zero exit code reported by git on error.
=head1 SEE ALSO
=head2 L<Git::Wrapper>
In particular, see the section on Error handling.
=head1 REPORTING BUGS & OTHER WAYS TO CONTRIBUTE
The code for this module is maintained on GitHub, at
Expand Down

0 comments on commit 77941cc

Please sign in to comment.