I wrote an API about a year ago using Dancer whose methods returned two items, a result object and an application error. If the result object was undef, then the application error would be defined, and that error was passed back up the object hierarchy to be returned to the caller.
During the code review for this API, I was criticized for not implementing this as a die or croak. It's a matter of taste -- for me, this type of error was application level, and not system level; it's something that could safely be reported back to the caller. IMO, a system level error would be something catastrophic like the database connection being unavailable.
Really, it's up to you -- make a decision how you're going to design your application, and after that, just be consistent.
Alex / talexb / Toronto
"Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds