Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Re^2: Error handling in Mojolicious

by clueless newbie (Curate)
on Jul 08, 2021 at 15:45 UTC ( [id://11134802] : note . print w/replies, xml ) Need Help??

in reply to Re: Error handling in Mojolicious
in thread Error handling in Mojolicious

If one takes the DBI as an example typically RaiseError is used in conjunction with eval, or a module like Try::Tiny or TryCatch, to catch the exception that's been thrown and handle it.

Let's look at the example that marto gives: (Note he states "Feel free to add error checking etc")

#!/usr/bin/perl use strict; use warnings; use Mojo::UserAgent; my $url = ' +g'; my $ua = Mojo::UserAgent->new; my $dom = $ua->get( $url )->res->dom; my $target = $dom->at('#file > a:nth-child(1) > img:nth-child(1)')->at +tr('src'); $ua->get('https:' . $target)->res->save_to('target.jpg') ;

Is there any way to "raise error" so I can utilize something like a try/catch?


In the code above the $url (in the first ->get) might be bad; the css selector (used in the ->at) might be invalid for the html returned; the argument to the second ->get could be bad and the ->save_to could fail due to some IO error. Adding checks for all these possibilities would be rather painful.

Replies are listed 'Best First'.
Re^3: Error handling in Mojolicious
by AnomalousMonk (Archbishop) on Jul 08, 2021 at 17:39 UTC
    Adding checks for all these possibilities would be rather painful.

    A long-winded version of what others have said (or implied) more succinctly.

    Writing code for exception handling is work, and work can be painful. But what's the alternative? Put your code into production without exception handling and hope it never fails? Dream on. (I assume we're talking about some sort of production application.)

    So what happens when your code fails without giving you the information you might get from even minimal exception handling? (Even a simple die statement will at least localize the failure to a particular line of source in a particular file.) Then you add checks for all the possible failures that might occur until you track down the culprit; i.e., you end up doing what you should have done to begin with. Add to this the fact that you may be doing all this at 3 AM because the production application needs to be ready for start-of-business at 8 AM and you learn what pain really is!

    If it's production code, it needs to be professional code, and professional code handles (or at least considers the handling of) errors.

    Update: Small wording change for clarity.

    Give a man a fish:  <%-{-{-{-<

      You called out the classic "Anyone can write a blog in a day" (or in a hackathon) paradox.

      It's easy to ignore all the hard parts and feel highly productive accomplishing a proof-of-concept in a short period of time. It usually turns out the POC is fairly trivial if it gets to ignore all the time consuming parts of the problem such as error handling, parameter validation, security, CICD pipelines, automated testing, documentation, and fitting into a larger ecosystem.


Re^3: Error handling in Mojolicious
by Fletch (Bishop) on Jul 08, 2021 at 19:05 UTC

    Not to disparage Mojo (or marto :) but that's one of the places where I have qualms about its docs. Some of the Mojo samples aren't what you should be aiming at because lots of places they'll show just chaining call after call after call. While it shows how simple things can be with Mojo it's eliding how you'd probably want to do it in a "real" application (and I'm speaking theoretically with large grains of salt here as I've never really done much in anger with Mojo myself).

    Taking your sample code (which was just the kind of thing I was trying to draw out :) I were I doing something like this in a production manner my inclination would be to put checking in the places that interface with the outside world.

    my $log = Mojo::Log->new; ## Or use $app->log . . . my $orig_result = $ua->get( $url )->result; if( $orig_result->is_success ) { my $dom = $orig_result->dom; my $target = $dom->at( q{...} )->attr( q{src} ); if( $target ) { my $save_result = $ua->get( q{https:} . $target )->result; if( $save_result->is_success ) { $save_result->save_to( q{target.jpg} ); } else { $log->error( qq{Problem fetching target '$target': }, $save_result->code, q{ }, $save_result->message ); } } else { $log->error( qq{Unable to locate CSS target in '$url'} ); } } else { $log->error( qq{Problem fetching '$url': }, $orig_message->code, q{ }, $orig_result->message ) }

    (Again, Mojo novice so I'm sure I may be corrected too.)

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.