The way the previous module deals with errors follows the way DBI mostly does it. If there is an error, it keeps it quiet and carries on. My module relies on the code using it to call success to check the operations worked out and calling error to find out what went wrong.
Currently, the new module uses the same approach. But I am wondering if I should use some other way to detect errors.
When I use DBI, I usually enable RaiseError, not only because it is the only sane way to handle failed transactions, but because it exits my program when things go wrong unexpectedly. And every time I enable RaiseError, it slightly annoys me, just like it annoys me that I have to enable strict and warnings. So for me, DBI dies, it does not silently hide errors. There are times when I want different behaviour, e.g. for a brute-force check if a table exists and is accessible. For that, perl has eval:
unless (eval { my @a=$dbh->selectrow_array('SELECT anycolumn FROM some +table'); 1 }) { $dbh->do('CREATE TABLE sometable ...'); }
Modules that require manual error checks after each function/method just annoy me. Even more when the functions/methods are incompatible with the well-working open FILE... or die schema, e.g. because they return a true value (e.g. the object itself) even when an error happens.
As the module connects with Stripe, it is only ever going to be used in a CGI environment. Therefore, the end user will be a web visitor. My concern is not the user experience of the end user. It is that the person who creates the web experience has an easy time of making a good user experience for the end user.
The end user experience is a problem of the CGI program, not a problem of the module that provides communication with an API.
Throwing an error to STDERR is not very helpful in a CGI environment
Directly writing to STDERR is not helpful AT ALL, not just in a CGI environment. Use die on error, use warn to warn of problems. That's it. If the user of your module chooses to ignore errors, the program will be aborted, with an error message written to STDERR. If the user wants some error handling, eval will allow to do any crazy thing you can't even think of. Similar for warnings, $SIG{__WARN__} (see perlvar) allows to handle warnings in ways you can't even think of. If you want to be friendly to the user of your module, provide a way to switch warnings on and off. Probably, warnings should be off by default, unless warnings are globally enabled by -w (i.e. $^W).
Throwing an error with die and stopping the web experience completely is not a very good solution because the error that will be displayed is probably meaningless to the end user.
Again, user expoerience is not the problem of a module providing access to an API. eval, Try::Tiny and the new try/catch/finally also work in a CGI environment. If the user of your module chooses to ignore all error handling, the end user will see a "500 Internal Server Error" page. Works as designed. If the user of your module chooses to delegate all error handling to CGI::Carp, the end user will see error message from deep within the application. Works as designed. If the user of your module chooses to wrap the entire code in a big eval, and show an "oops, something went wrong" page with a stupid cat photo in case of any error, the end user will see that. Works as designed. If the user of your module chooses to do reasonable error handling by wrapping functions/methods of your module in eval or try/catch and reacting to individual errors, the CGI can retry or fail with an error message that the end user can understand (e.g. "Sorry, the payment server seems to be down, please try again in five minutes").
Taking the end user through to the Stripe checkout with no information is not helpful to anyone. So it is better that my module doesn't stop the website from working, it allows the site creator to check for errors and get an idea of what the error is.
Right. Show the user a message like "Sorry, payment did not work." In parallel, send a message with internal details (i.e. called function and the real error message) to the admin. Easily implemented via eval or try/catch and some e-mail module. Heck, you could use a bugtracking system API to directly report the error into a bugtracking system and give the end user a bug ID ("Sorry, payment did not work. Please contact our support and mention the trouble ticket number 31415926535."). But: That's not your problem. It's a problem of the user of your module, the one writing the CGI. And using die is the sane way to report fatal errors.
Alexander
In reply to Re: Error handling in a module
by afoken
in thread Error handling in a module
by Bod
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |