2013/12/05

Futures advent day 5

Day 5 - Causing a Future to fail

Yesterday we looked at how to handle a Future that has failed. We can cause a Future to fail by invoking its fail method instead of done.

sub GET_checked
{
  my ( $url ) = @_;

  GET( $url )->then( sub {
    my ( $r ) = @_;
    if( $r->code !=~ m/^[23]../ ) {
      return Future->new->fail( $r->code." ".$r->message );
    }
    else {
      return Future->new->done( $r );
    }
  });
}

Here we have created a checked version of our hypothetical HTTP GET function, which returns a Future that will only be successful if the HTTP response was in the 2xx or 3xx ranges. If it gets an error (4xx or 5xx) then the Future will fail.

Another way to cause a future to fail is to simply throw a regular perl exception from a then or else code block. Each call to a code reference passed to these methods is wrapped in a eval {} block and causes the future to fail if the code throws an exception. This makes it easier to handle because now the chained future will fail, rather than causing the code that marked the preceding future as complete to propagate the exception it threw.

my $f = GET_checked("http://my-site-here.com/products.xml")
  ->then( sub {
    my ( $response ) = @_;
    if( $response->content_type ne "text/xml" ) {
      die "Expected Content-type: text/xml";
    }
    return Future->new->done( $response );
  });

This code is equivalent to code which uses Future->new->fail - the caller will not directly die with that exception, but instead the returned future will fail.

<< First | < Prev | Next >

No comments:

Post a Comment