Apertur-SDK

 view release on metacpan or  search on metacpan

README.md  view on Meta::CPAN

    $server_key->{publicKey},
    filename => 'photo.jpg',
    mimeType => 'image/jpeg',
);

print "Uploaded: $image->{id}\n";
```

## Error Handling

All API errors throw typed exceptions that inherit from `Apertur::SDK::Error`. Catch the specific subclass you care about, or catch the base class as a fallback. See [Error Handling documentation](https://docs.apertur.ca/errors).

```perl
use Apertur::SDK;
use Apertur::SDK::Error;
use Apertur::SDK::Error::Authentication;
use Apertur::SDK::Error::NotFound;
use Apertur::SDK::Error::RateLimit;
use Apertur::SDK::Error::Validation;

my $client = Apertur::SDK->new(api_key => 'aptr_live_...');

lib/Apertur/SDK.pm  view on Meta::CPAN

sandbox environment.

    # API key
    my $client = Apertur::SDK->new(api_key => 'aptr_live_...');

    # OAuth token
    my $client = Apertur::SDK->new(oauth_token => $access_token);

=head1 ERROR HANDLING

All API errors throw typed L<Apertur::SDK::Error> objects:

    use Apertur::SDK;
    use Apertur::SDK::Error::Authentication;
    use Apertur::SDK::Error::NotFound;
    use Apertur::SDK::Error::RateLimit;
    use Apertur::SDK::Error::Validation;

    eval {
        my $session = $client->sessions->create(label => 'test');
    };

lib/Apertur/SDK/Error.pm  view on Meta::CPAN


sub new {
    my ($class, %args) = @_;
    return bless {
        status_code => $args{status_code} // 0,
        code        => $args{code}        // '',
        message     => $args{message}     // 'Unknown error',
    }, $class;
}

sub throw {
    my ($class, %args) = @_;
    die $class->new(%args);
}

sub status_code { return $_[0]->{status_code} }
sub code        { return $_[0]->{code} }
sub message     { return $_[0]->{message} }

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

lib/Apertur/SDK/Error.pm  view on Meta::CPAN


=head1 NAME

Apertur::SDK::Error - Base exception class for Apertur API errors

=head1 SYNOPSIS

    use Apertur::SDK::Error;

    eval {
        Apertur::SDK::Error->throw(
            status_code => 500,
            code        => 'INTERNAL',
            message     => 'Something went wrong',
        );
    };
    if (my $err = $@) {
        if (ref $err && $err->isa('Apertur::SDK::Error')) {
            warn "API error: " . $err->message;
        }
    }

=head1 DESCRIPTION

Base error class for all Apertur SDK errors. All API errors are represented
as blessed objects that can be thrown with C<die> and caught with C<eval>.

=head1 METHODS

=over 4

=item B<new(%args)>

Constructor. Accepted keys: C<status_code>, C<code>, C<message>.

=item B<throw(%args)>

Class method that creates and throws (via C<die>) a new error.

=item B<status_code>

Returns the HTTP status code.

=item B<code>

Returns the error code string (e.g. C<NOT_FOUND>).

=item B<message>

lib/Apertur/SDK/HTTPClient.pm  view on Meta::CPAN

        $body = decode_json($res->decoded_content);
    };
    if ($@) {
        $body = { message => "HTTP $status" };
    }

    my $message = $body->{message} || "HTTP $status";
    my $code    = $body->{code};

    if ($status == 401) {
        Apertur::SDK::Error::Authentication->throw(message => $message);
    }
    elsif ($status == 404) {
        Apertur::SDK::Error::NotFound->throw(message => $message);
    }
    elsif ($status == 429) {
        my $retry_after = $res->header('Retry-After');
        $retry_after = defined $retry_after ? int($retry_after) : undef;
        Apertur::SDK::Error::RateLimit->throw(
            message     => $message,
            retry_after => $retry_after,
        );
    }
    elsif ($status == 400) {
        Apertur::SDK::Error::Validation->throw(message => $message);
    }
    else {
        Apertur::SDK::Error->throw(
            status_code => $status,
            code        => $code,
            message     => $message,
        );
    }
}

1;

__END__

t/01_client.t  view on Meta::CPAN

        retry_after => 30,
    );
    isa_ok($rl, 'Apertur::SDK::Error');
    is($rl->status_code,  429,         'rate limit status_code');
    is($rl->retry_after,  30,          'rate limit retry_after');

    my $val = Apertur::SDK::Error::Validation->new(message => 'Bad input');
    isa_ok($val, 'Apertur::SDK::Error');
    is($val->status_code, 400, 'validation status_code');

    # Test throw mechanism
    eval { Apertur::SDK::Error::NotFound->throw(message => 'Gone') };
    my $caught = $@;
    isa_ok($caught, 'Apertur::SDK::Error::NotFound');
    is($caught->message, 'Gone', 'thrown error message');
};

# --- Signature verification ---

subtest 'Signature verification' => sub {
    plan tests => 6;

    use Apertur::SDK::Signature qw(
        verify_webhook_signature
        verify_event_signature



( run in 0.460 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )