How to catch Exception Message in Erlang? - exception

This is the Exception message thrown by Gen_server when its not started.
(ankit#127.0.0.1)32> R11 = system_warning:self_test("SysWarn").
** exception exit: {noproc,
{gen_server,call,
[system_warning_sup,
{start_child,
{system_warning_SysWarn,
{system_warning,start_link,[{system_warning_SysWarn}]},
permanent,10,worker,
[system_warning]}},
infinity]}}
in function gen_server:call/3
in call from system_warning_sup:'-start_child/1-lc$^0/1-0-'/1
in call from system_warning:self_test/1
(ankit#127.0.0.1)33> R11.
* 1: variable 'R11' is unbound
Now, What I want to do is to catch this exception message & put into variable R11 (showed above as unbound). I want to do so because if gen_sever is not started then I want to start after getting this message. I also tried using handle_info but not able to trap the exception or may be not able to implement it correctly. Can any body please help me with this problem providing some code for example.

Both the answers from #W55tKQbuRu28Q4xv and #Zed are correct but a little terse. :-)
There are two ways to locally catch an error: catchand try. Both will also catch non-local returns generated by throw.
catch is the older and simpler of the two and has the syntax catch Expr. If an error occurs in the expression being evaluated then catch returns {'EXIT',ErrorValue}, otherwise it just returns the value of the expression. One problem with it is that there is no way to see how the error return value has been generated so it can easily be faked in the expression. In the same way you can't see if the return value comes from a throw. N.B. this is not a bug but a feature. Also it is a prefix operator with a low priority so you would normally use it like:
R11 = (catch system_warning:self_test (....))
to avoid confusion. This was a mistake, it should have been catch ... end.
throw is more complex and allows you much greater control over over what to catch and how to handle both the normal returns and error/non-local returns. See the manual for a full description. #Zed's example shows the simplest case which catches everything.

> try
> R11 = system_warning:self_test("SysWarn")
> catch
> Ex:Type -> {Ex,Type,erlang:get_stacktrace()}
> end.

Try to use 'catch':
R11 = catch system_warning:self_test (....)

Related

Expression statement to cover all exceptions in catch exception strategy in mule?

I have scenario like if 3 errors occurs then one catch block should execute other than these three other catch block should execute.
I have tried by placing 3 exceptions : #[exception.causedBy(java.net.UnknownHostException) ||exception.causedBy(java.net.ConnectException)||exception.causedBy(org.mule.transport.jms.redelivery.MessageRedeliveredException)] in first catch-1 when condition and left second catch as blank. But what issue I'm facing here is control is directly entering into second catch-2. I have tried by pacing #[exception.causedBy(*)] in second catch-2. But it didn't work can anybody suggest on this?
Thanks.,
It sounds like the exception being thrown is not any of those exceptions so it will enter the second catch. If you want to catch all exceptions, dont add a 'when' attribute or just use a catch-exception-strategy or maybe #[exception.causedBy(java.lang.Exception)]

AllegroServe Exception Handling

How can I avoid getting an error when passing as argument to the function do-http-request an invalid host.
Is there any way that I can catch the error like the Java's exception-handling mechanism ?
Sure, CL has a very nice condition system. One easy option would be wrapping the call to do-http-request in ignore-errors, which returns nil (and the condition as a second value) if an error condition was signalled in the wrapped code. You could then check for nil afterwards.
If you want something more like exception handling in Java, just use handler-case and add an appropriate error clause (I don't have AllegroServe installed, but I suppose you get a socket-error for providing a wrong URL – just change that part if I misread):
(handler-case
(do-http-request …)
(socket-error ()
…))
If you need finally-like functionality, use unwind-protect:
(unwind-protect
(handler-case
(do-http-request …)
(socket-error (condition) ; bind the signalled condition
…) ; code to run when a socket-error was signalled
(:no-error (value) ; bind the returned value
…)) ; code to run when no condition was signalled
…) ; cleanup code (finally)
You can even get more fancy, and e.g. use handler-bind to handle the condition stack upwards by invoking a restart somewhere down the stack, without unwinding it. For example, if do-http-request provided a restart to try again with another URL, you could handle your error condition by invoking that restart with a new URL to retry. I just mention this for the sake of completeness – it would be overkill for your use case, but being able to resume (possibly expensive) computations easily can be a rather convenient feature.

Erlang error handling philosophy - case vs throw

I'm writing a REST service in Erlang and need to verify the received data before passing it to other internal functions for further processing; in order to do that, I'm currently using nested case expressions like this:
case all_args_defined(Args) of
true ->
ActionSuccess = action(Args),
case ActionSuccess of
{ok, _} -> ...;
{fail, reason} -> {fail, reason}
end,
_ ->
{fail, "args not defined"}
end,
...
I realize this is kind of ugly, but this way I can provide detailed error messages. Additionally, I don't think the usual make it crash philosophy is applicable here - I don't want my REST service to crash and be restarted every time somebody throws invalid arguments at it.
However, I'm considering abandoning all those cases in favor of an umbrella try/catch block catching any badmatch errors - would this work?
fun() ->
true = all_args_defined(Args),
{ok, _} = action(Args).
%% somewhere else
catch fun().
Since what you want to achieve is error reporting, you should structure the thing around the execution of actions and reporting of the result. Perhaps something like this:
execute(Action, Args) ->
try
check_args(Args),
Result = action(Action, Args),
send_result(Result)
catch
throw:{fail, Reason} ->
report_error(Reason);
ExceptionClass:Term ->
%% catch-all for all other unexpected exceptions
Trace = erlang:get_stacktrace(),
report_error({crash, ExceptionClass, Term, Trace})
end.
%% all of these throw {fail, Reason} if they detect something fishy
%% and otherwise they return some value as result (or just crash)
action(foo, [X1, X2]) -> ...;
action(foo, Args) -> throw({fail, {bad_arity, foo, 2, Args}});
action(...) -> ...
%% this handles the formatting of all possible errors
report_error({bad_arity, Action, Arity, Args}) ->
send_error(io_lib:format("wrong number of arguments for ~w: "
"expected ~w, but got ~w",
[Action, Arity, length(Args)]));
report_error(...) -> ...;
report_error({crash, Class, Term, Trace}) ->
send_error(io_lib:format("internal error: "
"~w:~w~nstacktrace:~n~p~n",
[Class, Term, Trace])).
I've had this problem while developing an application that create users.
I first come with a solution like this:
insert() ->
try
check_1(), % the check functions throw an exception on error.
check_2(),
check_3(),
do_insert()
catch
throw:Error1 ->
handle_error_1();
throw:Error2 ->
handle_error_2();
_:Error ->
internal_error()
end.
The problem with this solution is that you lose the stack trace with the try...catch block.
Instead of this, a better solution is:
insert() ->
case catch execute() of
ok -> all_ok;
{FuncName, Error} ->
handle_error(FuncName, Error);
{'EXIT', Error} ->
internal_error(Error)
end.
execute() ->
check_1(), % the check functions throw an exception on error.
check_2(),
check_3(),
do_insert().
This way you have the full error stack on Error.
I have faced exactly the same question when writing my own REST services.
Let's start with the philosophy:
I like to think of my applications like a box. On the inside of the box are all of the parts I built and have direct control over. If something breaks here, it's my fault, it should crash, and I should read about it in an error log. On the edge of the box are all of the connection points to the outside world - these are not to be trusted. I avoid exception handling in the inside parts and use it as needed for the outer edge.
On similar projects I have worked on:
I usually have about a dozen checks on the user input. If something looks bad, I log it and return an error to the user. Having a stack trace isn't particularly meaningful to me - if the user forgot a parameter there is nothing in my code to hunt down and fix. I'd rather see a text log that says something like: “at 17:35, user X accessed path Y but was missing parameter Z”.
I organize my checks into functions that return ok or {error, string()}. The main function just iterates over the checks and returns ok if they all pass, otherwise it returns the first error, which is then logged. Inside of my check functions I use exception handling as needed because I can't possibly consider all of the ways users can screw up.
As suggested by my colleagues, you can alternatively have each check throw an exception instead of using a tuple.
As for your implementation, I think your idea of using a single exception handler is a good one if you only have the single check. If you end up needing more checks you may want to implement something like I described so that you can have more specific logging.

How can I write an exception stack trace in erlang after catching it?

Suppose I have something like this :
try code_that_fails()
catch _:_ -> .....
How do I print the stacktrace in the catch block? That block catches all exceptions, but I don't know how to print the stack...
Can you help me?
From Erlang 21.0 onwards, there's a new official way to get the stack trace. An optional pattern match in the try expression on the third parameter in the exception, which will contain the stack trace:
try
code_that_fails()
catch
_:_:Stacktrace ->
erlang:display(Stacktrace)
end
Older versions (OTP 20 and below)
For versions of Erlang/OTP 20 and below, you need to use get_stacktrace/0, which allows you to get the stacktrace of the last exception in the calling process:
try
code_that_fails()
catch
_:_ ->
erlang:display(erlang:get_stacktrace())
end
An answer for your question is:
io:format("Backtrace ~p~n", [erlang:get_stacktrace()])
The current function is at the head of the list. Read more in man 3erl erlang or erlang:get_stacktrace/0
In your example, you don't need the try; you can just do
result = (catch code_that_fails()).
If an exception is raised, catch returns a tuple that contains the error code and stack trace.
Note that this is generally considered bad practice as it can mask exceptions. The stacktrace approach described in another answer is almost certainly what you want.
try is an extension of the original catch functionality; if you use it, you need to specify clauses for each exception type you would like to catch, and handle them appropriately. See sections 6.18/6.19 of the Erlang reference manual for details and clear examples.

Using Exceptions exceptionally

This is a refactoring question.
try
{
string line = GetFirstLineFromFile(); //Gets first line from a text file, this line would be a number.
int value = ConvertToInteger(line); // Gets the integer value from the string.
int result = DivideByValue(value); // Divides some number with the value retrieved.
}
catch(Exception ex)
{
}
My main concern is, what is the best approach for exception handling in such situations. Certainly wrapping the whole thing in a single try catch is like saying I expect an exception about everything. There must be some place we catch a generic exception right?
Just don't catch a "generic exception".
How can you possibly handle ANY exception and know how to keep your application in a clean state ?
It hides bugs and it's a really bad idea.
Read this serie of posts on catch (Exception).
You need to think about what exceptions can be thrown from the methods in the try block, as well as which ones of those you can deal with at the current level of abstraction.
In your case, I'd expect that the getFirstLineFromFile methods, for example, can definitely throw exceptions you'd want to catch here. Now whether you wrap and rethrow the exception, or take other action, depends on whether you can actually deal with the exception at this level. Consider the case where you have a default file you can fall back to - the approach may just be to log a warning and continue with the default. Or if the whole application is based on reading a file supplied by the user, then this is more likely to be a fatal exception that should be propagated up to the top level and communicated to the user there.
There's no hard-and-fast rule like "always throw" or "never throw"; in general, I consider that one should throw exceptions whenever there's an exceptional-type situation that is not considered a normal result of the method, and consequently cannot be adequately described by the return type of the method. (For example, an isValidDbUser method returning boolean might be able to handle SQLExceptions as just return false; but a getNumProductsRegisteredInDB returning an int should almost certainly propagate an exception).
Don't listen to the (hordes) of people that will tell you that you should never catch multiple exceptions in one big general block. It's a perfectly reasonable way to do general error handling in some cases, which is why the ability to do so exists in the language.
There will be some exceptions that you can do something specific and useful about (i.e. recover from them in the catch block.) These are the kinds of exceptions that you want to catch individually, and as close to the place where they occur as possible.
But the majority of exceptions that you'll face in real life will be completely unexpected, unchecked exceptions. They are the result of programmer error (bugs), failed assertions, failing hardware, dropped network connections, etc.
You should design your software defensively, by designating specific "chokepoints" to handle these unpredictable exceptions with a minimum of disruption to the rest of the application. (Remember, in many cases, "handling" the exception often just means aborting the current operation and logging an error or otherwise telling the user that an unexpected error occurred.)
So for example, if your program saves a file to the disk, you could wrap the entire save operation in a try block to catch things that goes wrong during the save:
try {
// attempt to perform the save operation
doSave();
} catch (Throwable t) {
// tell the user that the save failed for unexpected reasons
// and log the error somewhere
informUser("save failed!");
log("save failed!", t);
} finally {
// last minute cleanup (happens whether save succeeded or failed)
...
}
Notice that we choose a nice chokepoint method here ( doSave() ) and then stop any unexpected errors from bubbling up any further than this point. The chokepoint represents a single, cancellable operation (a save). While that operation is obviously toast if you're getting an unexpected exception, the rest of the application will remain in a good state regardless of what happens on the other side of the chokepoint.
Also notice that this idiom does NOT stop you from handling some of your exceptions further down in doSave() somewhere. So if there are exceptions that might get thrown that you can recover from, or that you want to handle in a special way, go ahead an do so down in doSave(). But for everything else, you have your chokepoint.
You might even want to set up a general uncaught exception handler for your entire program in your main method:
public static void main(String [] args) {
try {
startApplication();
} catch (Throwable t) {
informUser("unexpected error! quitting application");
log("fatal application error", t);
}
But if you've set your other chokepoints up wisely, no exceptions will ever bubble up this far. If you want to make your general error handling complete, you can also create and assign an UncaughtExceptionHandler to important threads, including your main thread or the AWT thread if you are using Swing.
TL;DR; Don't believe the dogma that you should always catch exceptions as specifically as possible. There are times when you want to catch and handle a specific exception, and other times when you want to use chokepoints to catch and deal with "anything else that might go wrong".