DBIx::Exceptions

Arthur Axel "fROOH" Schmidt

Purpose

To educate audience of exceptions in Perl and briefly introduce DBIx::Exceptions

What is an Exception?

According to wikipedia, an exception is a special condition that changes the normal flow of program execution

NOT an error code

my $fh;
if (!open $fh, '>', 'filename') {
   warn "couldn't open file!"
}

Why should I use exceptions?

When should I use exceptions?

Problems with exceptions

Super Basic Exceptions in Perl

my $x = rand 10;
die "half-broken: $x" if $x < 5

Vanilla Perl Exceptions

eval {
  my $x = rand 10;
  die "half-broken: $x" if $x < 5
};
say 'coin flip fail'
   if defined $@ && $@ =~ /half-broken: (.+)/;

:-/


Modern Exceptions

Object Exceptions

eval {
  my $x = rand 10;
  die Foo->new({ num => $x })
    if $x < 5
};
say 'coin flip fail'
   if ref $@ && $@->isa('Foo');

Exception::Class

Exception::Class Exception

package MyApp::Exceptions;
use Exception::Class (
   'MyApp::Exception::Foo' => {
      fields => ['num'],
   },
);

Exception::Class in action

eval {
  my $x = rand 10;
  MyApp::Exception::Foo->throw( num => $x )
    if $x < 5
};
say 'coin flip fail'
   if Exception::Class->caught('MyApp::Exception::Foo');

Throwable

Throwable Exception

package Foo;

use Moose;
with 'Throwable';

has num => (
   is => 'ro',
   isa => 'Num',
);

1;

Throwable Exception in action

eval {
  my $x = rand 10;
  Foo->throw({ num => $x })
    if $x < 5
};
say 'coin flip fail'
   if defined $@ && ref $@ && $@->isa('Foo');

Try::Tiny

Try::Tiny in action

try {
  my $x = rand 10;
  Foo->throw({ num => $x })
    if $x < 5
} catch {
   say 'coin flip fail'
     if ref $_ && $_->isa('Foo')
};

TryCatch

TryCatch in action

try {
  my $x = rand 10;
  Foo->throw({ num => $x })
    if $x < 5
} catch (Foo $e) {
   say 'coin flip fail with num of ' . $e->num
}

Advanced TryCatch in action

try { ... }
catch (Foo $e) { ... }
catch (Bar $e) { ... }
catch (Baz $e where { $e->num > 5 }) { ... }

Carp::Always

NOW YOU KNOW EVERYTHING

Old School Perl Database Exceptions

eval { $sth->execute };
if ($@ =~ /unique \s+ constraint \s+ violated/ix) {
   ...
}

:-/

Introducing DBIx::Exceptions

DBIx::Exceptions - Database exceptions for all RDBMS' Ever

What it do's?

Planned Support for DBIx::Exceptions

Setup

my $dbh = DBI->connect($dsn, $username, $password);

$dbh->{HandleError} =
   DBIx::ParseException->handler({ dbh => $dbh });

Example Usage (1)

try {
   my $sth = $dbh->prepare(
      'INSERT INTO Emails (email) VALUES (?)'
   );
   $sth->execute('frew@gmail.com')
      for (1..2);
} catch (
   DBIx::Exception::NotUnique $e
   where { $e->column eq 'email'}
) {
   ...
};

Example Usage (2)

try {
   my $sth = $dbh->prepare(
      'INSERT INTO Rmails (email) VALUES (?)'
   );
   $sth->execute('frew@gmail.com');
} catch (
   DBIx::Exception::NoSuchTable $e
) {
   say $e->table . ' nt lolz'
};

Example Usage (3)

try {
   my $sth = $dbh->prepare(
      'INSERT INTO Emails (emisl) VALUES (?)'
   );
   $sth->execute('frew@gmail.com');
} catch (
   DBIx::Exception::NoSuchColumn $e
) {
   say  column: ' . $e->column .
      ' does not exist on table ' $e->table
};

Other Gotchas

Questions?

THE END