freddo411 has asked for the wisdom of the Perl Monks concerning the following question:

All,

Hi, I'm using CGI:Application version 3.1. The load_tmpl() method calls HTML::Template which croaks when the specified template can't be found. This has the undesirable behavior of returning a server error to the browser.

I'd like to trap this error and handle it gracefully. I'm thinking about overriding load_tmpl() and wrapping it in an eval block...etc.

Has anyone else had this idea for dealing with this issue? How do you handle this issue?

Cheers

-------------------------------------
Nothing is too wonderful to be true
-- Michael Faraday

  • Comment on CGI::Application/HTML::Template error handling

Replies are listed 'Best First'.
Re: CGI::Application/HTML::Template error handling
by perrin (Chancellor) on Oct 03, 2003 at 23:38 UTC
    What would you consider reasonable behavior when the template you tried to run is not found? It sure sounds like a croaker to me.
      WHile I understand the H::T doesn't have much it can do (besides croak) if it can't get to the specified template, dieing without a message to the user isn't a viable option in a robut web application, and is a minor PITA when developing. Since typically the coding and template writting is done by different folks, the coder and testers will often have this situation arise.

      The call in question, load_tmpl, would normally return a template object. I'm thinking it should return either a null, or something else that can be easily tested so that the application as a whole can deal nicely with the situation.

      In a general sense, if you have an object constructor method, what is the "best practices" behavior for the case where it cannot create the object?

      -------------------------------------
      Nothing is too wonderful to be true
      -- Michael Faraday

        My basic theory is that there are two kinds of exceptions: those you can recover from (e.g. user input problem, or a situation where you have a backup approach to try) and those you can't (the database server exploded, some buggy code called a sub with the wrong args). I usually call the second type "system exceptions." There's really no point in catching this kind of exception at a low level, since there's nothing you can do to recover from it seamlessly. Your goal at this point is to get the error into the log, and send a pretty error page to the user.

        The simplest approach to this is to just make a nice custom error page and tell your web server to use it. If you can't do that, you can put an eval at the very top level of your program so that it will catch any uncaught exceptions and have a chance to log them and send the pretty page. There is some advantage to doing it that way, in that you can do more extensive logging, including a stack trace in some situations.

        I definitely think croak'ing is the correct behavior for H::T in the situation you mention. Returning error codes is a major source of bugs, because no one ever checks them consistently. Just look at DBI. People who use it without RaiseError turned on invariably have code where they fail to check return codes, resulting in failures further along in the code and highly confusing error messages. Throwing an exception is a much better way to handle an error that prevents the successful completion of a method call.

Re: CGI::Application/HTML::Template error handling
by jeffa (Bishop) on Oct 04, 2003 at 13:37 UTC
    I haven't played with CGI::Application enough, but i would attempt to override the load_tmpl() method. However, instead of wrapping in eval, i would first check to see if the template truly exists (a simple -f and/or -r test should do the trick).

    If the template does exist, then call

    $self->SUPER::load_tmpl($tmpl_file, @extra_params);
    (i suppose you could also just pass @_ instead).

    If it doesn't exist, then call
    $self->SUPER::load_tmpl('404.tmpl', @extra_params);
    where 404.tmpl is your canned '404 Not found' response.

    Hope this helps.

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)