New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Need a substitute for Perl 5 die with newline for raising end-user errors? #59
Comments
Personally, I like the |
On #perl6-dev this was discussed just now at some length, and a couple things to note:
exit "This is not a graphical display, I can't draw anything!";
# or, equivalently,
exit X::UserError::NoGraphics.new(); and it would But even as now stands, assuming these exit variants existed, then, for example, a single program that can run in a CLI or a GUI could deal with this by redirecting |
I don't like I've been making a |
@CurtTilmes It’s hard to get the With the I hear you with regards to |
In Perl 5,
die
’s message could be terminated with a newline to suppress diagnostic messages (line number at minimum, up to full backtrace if you ask for it—in this issue I’ll just call it “backtrace” for simplicity, whatever it is—it’s anything added by the language to the message given todie
).This suppression via newline is no longer possible in Perl 6 (and for very good reasons that I shouldn’t have to mention here).
It does leave an open question, though: in directly interactive executables, how should the programmer idiomatically handle end-user errors such as incorrect usage (apart from
USAGE
itself, of course)—things like attempting an operation the user doesn’t have access to, trying to run a graphical program in a non-graphical context, etc.? It seems like the choices are:Use
die
anyway and put up with the backtrace printed to users.a. It’s easy
b. It’s familiar
c. It doesn’t need special-casing
a. A backtrace from a program in a non-debugging context, especially inside error-checking code, is user-unfriendly because it’s ugly;
b. It’s also user-unfriendly because it buries the useful part of the message at the top of a lot of debugging cruft that is not useful to the end-user
c. For the programmer, it makes it somewhat more difficult to do a
CATCH
-all at the top level for production code that turns the language backtrace into something that can be communicated by nontechnical users to support, since user errors are not something that needs such special handlingFollow the method recommended in
die
’s docs: create a top-levelCATCH
-all which changes the top-level uncaught behavior so it doesn’t print the backtrace, and then usedie
.a. It’s simple
b. It’s consistent
a. It requires boilerplate that may not be obvious to many programmers who won’t think to look at
die
’s documentation and will contrive a solution withexit
instead.b. For executables I’ll call “targeted at the semi-technical user”, it’s common practice to exit with nice-human messages for things that the program checks, but to “toss its cookies” with a backtrace if it hits an exception unaccounted for. Besides being most parsimonious for the programmer, this seems like very reasonable behavior for users who are likely to know the difference between most “my fault” problems and “bugs”—and a top-level
CATCH
-all makes this more difficult to be the default behavior.Create an exception class (
X::UserMessage
?) that (along with its subclasses) restores the Perl 5die
-with-newline behavior; if it reaches the top level, only the message of the exception is printed, and not a backtrace.a. It’s consistent with most of the rest of exception handling and would easily extend to Failures as well;
b. It could promote the use of proper exceptions instead of ad-hoc stringy exceptions, which may be desirable for code like we’re talking about (notably, it makes i18n and l10n for messages that may be expected to be seen by non-technical users much easier, since it’s confined to one place).¹
c. Most CPAN code won’t have to worry about this class of exception at all, since it isn’t concerned with end-user exceptions
d. You can convert any non-
X::UserMessage
exceptions into one complete with instructions for reporting bugs with a simpleCATCH
at the top level that catches everything butX::UserMessage
.e. Following from the above, it makes the “semi-technical user” oriented behavior of nice messages for things you want to gently inform the user about, but “cookie tossing” for unexpected failures, the normal case without any special handling.
a. It seems a little magical.
b. It doesn’t allow for a simple
CATCH
-all at the top level with no special-casing—but as mentioned in the last Pro point, it obviates theCATCH
entirely in the most likely use case where one would do that.Create a new word (maybe
exitwith
) to give some syntactic sugar toa. It’s closest to Perl 5’s
die
-with-newline behaviorb. It’s simple
c. It’s easy
a. It requires a new word
b. It promotes ad-hoc stringy error messages, making i18n/l10n of messages more difficult
c. It’s not as easily caught (and by spec, isn’t necessarily catchable at all?).
d. Since it’s not as easily caught, it will prevent finalizers in ways that a special exception class wouldn’t.
(Throwing this in for completeness:) Adopt the Perl 5 behavior of paying attention to a trailing newline. I mention it, but it seems (to me) patently ridiculous behavior for Perl 6. A not-so-crazy alternative, however, would be to add to
die
a backtrace-suppression boolean flag (with an accompanying boolean field in exceptions, I presume?) that would stop the backtrace if and only if the exception gets all the way to the top level uncaught.¹ I don’t think the promotion of proper exceptions is anything to sneeze at; I suspect that for programmers who use stringy ad-hocs for convenience’s sake, they probably have a very large overlap with programmers who only `die` at all for things they actually check for. So making this class of thing easier with real exceptions than with strings would be a win for non-ad-hoc exceptions.
The text was updated successfully, but these errors were encountered: