[Catalyst] Re: Perl::Rails?

Sebastian Riedel sri at oook.de
Fri Dec 9 16:33:32 CET 2005


09.12.2005 15:02 Brandon Black:
> I would agree that debugging is a weakness in Catalyst at the moment.
> I run into this weakness in two ways primarily.  The first is that
> while the failure of a Controller to have correct syntax results in
> the whole app failing to start and showing you the parse error (a good
> thing), if you make a similar syntax mistake in a Model class (using
> the standard CDBI/DBIC autoloader models), you get no such warning.
> The first you hear of it is that some method you're trying to call
> from that model doesn't exist at runtime.  This came up before and
> someone had a solution for it, but I couldn't find the email earlier,
> and in any case the real solution should just work for the
> default/naive case.

Works perfectly with Catalyst 5.61 and Module::Pluggable::Fast 0.17.
Please send a testcase.

>
> The bigger issue, IMHO, is that exceptions provide no stack trace.  If
> the exception occurs directly in your Controller classes, it's a
> no-brainer.  But when the death message comes from deep in the bowels
> of some other model you didn't write (say a death in a DateTime
> constructor, or a death deep inside Catalyst::, etc), the error
> message is far from helpful in tracking down where you likely made a
> mistake in your application code.

Again, works perfectly with 5.61, testcase please.

>
> I haven't investigated this enough yet to know whether there's some
> larger issue that makes it more difficult than it seems, but it seems
> like we should be able to add an exception-handling class to the
> Catalyst infrastructure that does proper stack traces.  I rolled my
> own for another part of my application that's based on the concepts in
> Error.pm, but considerably simpler, shorter, and more efficient.  I'd
> be more than willing to donate that to Catalyst, but I'm not sure that
> most Catalyst devs would be willing to start using the try/catch
> idiom, given the issues various people have pointed out in the past
> (closures, return values).  Once you get used to the idiom it's a
> no-brainer to use though, even with return vals:
>
> sub myroutine {
>    my $retval = try {
>         ... some code which may My:Exception:Something->throw(...);
>         ... or also some external module code which may die "foo";
>         ... You can do just about anything in a try block - I
> generally wrap entire long-running daemons in try blocks.
>         return 3;
>    }
>    catch My::Exception::Foo with {
>         ... we consider this exception nonfatal
>         return 2;
>    }
>    catch My::Exception::Bar with {
>         .... this one deserves a rethrow to some outer context
> (eventually the outermost context is straight up perl death with stack
> trace)
>         $_->rethrow();
>    }
>    catch SYSERR with {
>         .. SYSERR is a special exception class which matches non-OO
> "die" statements (and they can be optionally rethrown with $_->rethrow
> just like everything else)
>    }
>    catch All with {
>          ... had this catch-all not been here, the default would have
> been to rethrow anything not explicitly caught, as above.  You
> shouldn't normally be using this much, although it's good at the
> highest contextual layer of a webapp to use it to HTML-ify the
> error+stacktrace that came from below, or if you're running some very
> untrustable deadly code that you expect to fail in odd ways from time
> to time and you wish to handle it gracefully in all cases.
>          warn "Exception happened: $_";
>          return 45;
>    };
>    return $retval;
> }
>
> My simplified version only defines try/catch clauses and the special
> All and SYSERR exception classes (with different names at the moment
> though, that's easy to change).  It skips the whole except/finally/etc
> clauses as I didn't see much practical use for them (it seems you can
> do those things in other ways).  User-defined exception class names
> derive from the All class, as does SYSERR, and the "with" matching
> pays attention to ->isa().  So catching My::Exception::Base will catch
> My::Exception::DerivedFromBase.  And all exceptions that occur within
> a try {} block stringify to include a stack trace, even plain old
> "die".  Also, the stacktrace filters itself out, so that you don't see
> all the extra lines in the stacktrace from the try/catch clauses and
> internal subroutines of the exception module either, as if you weren't
> using one.  I'll probably CPAN it as a generic module sometime in
> January (once I'm past a couple of deadlines here at work and have
> some time) anyways.

perldoc Catalyst::Exception

--
sebastian




More information about the Catalyst mailing list