Handling failures with Either -> Where is the stacktrace? - java

I heard from some people that in Scala we tend (like other functional languages) to not break the control flow... Instead by convention we return the error in an Either Left.
But how do we get the stracktrace from that exception?
For now i return in the Left a simple Error case class with a code, message and cause (Error too). But if i have an error, i can't get the stacktrace.
If my application become complexe it may be hard to find the code block that returned that Error... The root cause is essential.
So what do we do in practice?
Should i return, instead of a custom Error, the java type Exception or Throwable in my Left?
What's the best practice for Scala exception handling without loosing important informations such as the stacktrace and the cause?

I'd suggest using Either[java.lang.Throwable, A] (where Throwable still gives you access to the stack trace), and (in general) making your custom error types extend java.lang.Exception.
This is the practice used by Dispatch 0.9, for example, where Either[Throwable, A] is used to represent computations that may fail, and the custom error types look like this:
case class StatusCode(code: Int)
extends Exception("Unexpected response status: %d".format(code))
Scalaz 7's Validation.fromTryCatch(a: => T) also returns a Validation[Throwable, T], where Validation is roughly equivalent to Either.

Related

How to handle exceptions in Java in functional way

How to handle exceptions in Java in functional way?
If I do:
try{
}
catch(Exception e)
{
//log it
// throw exception?
}
and catching the exceptions, what should I return:
Throw the exception?
Else send some error code ( similar to how we handle in C languages )
Because functional programming says:
A function should always return the same type.
Given this scenario, it becomes for certain given input it will throw the exception. Hence its not a pure functional style.
How one should handle this case in Java?
Well even in functional programming, exceptions are not considered as return values.
Take for instance, this segment of SML code:
fun remove_card (cs, c, e) =
case cs of
[] => raise e (* raise exception and stop execution of the function *)
| x::xs => if x = c
then xs
else x::remove_card (xs,c,e)
As you can see, when the exception is raised, we forget about the original return type of the function (a list). It is in this moment that an error situation has happened in your application and you want to handle it to avoid your application from crashing. So, you would not be breaking the purity of your functional programming, since exceptions are thrown, not returned, in order to handle the instability caused by unexpected values/behavior inside your application.
Don't both log and rethrow, if you feel like you want to put some information down and rethrow then wrap the exception. Log only if you are done dealing with this exception and plan on returning a value from the method. Not some error indication like in C, actual value. For example you tried to download something but failed, however you still have a fallback. If you are trying to indicate an error you throw an exception.
Just to add, a lot of times people deal with exceptions by logging in place and returning a null. In the vast majority of cases this is the wrong thing to do as it will only lead to frustration of dealing with NPEs in completely different places

why "throws exception" in java but not in c++?

I'm learning to use java, I think I already know the basics of C++. But, as I just started learning java, the first bits of 'hello world' program I noticed uses 'throws exception' when initiating the main function in the main class. Why is it used? Do we do something similar in c++? Is returning 0 in int type main function in c++ a similar thing?
In Java, specifying that a methodthrows SomeException means that any method calling that method will have to either catch or itself throw that exception. In the case of the main function, it just means that you don't have to catch any exceptions that may occur directly in the main method, they will instead be passed on to the underlying runtime, resulting in a stack trace print and program exit.
It isn't, or at least, I've never seen a main in Java which
did it. I'm not even sure that it's legal. (Given the way Java
uses exceptions, it shouldn't be. Only RuntimeException and
Error should propagate out of main.)
Java tends to overuse exceptions; especially, it uses exceptions
in cases where return values would be more appropriate (e.g.
things like not being able to open a file). In a correct
program, these exceptions must be handled (just as in a correct
program, C++ returned error codes, or in the case of input and
output, the stream state, must be handled). Java uses the
exception specifier to declare these exceptions (and only
these—it isn't necessary to declare things that would be
an exception in C++).

How is exception handling implemented in Java?

How is exception handling implemented in higher-level programming languages (like Java)? By this, I don't mean how to use exceptions within a language; I mean how the compiler generates code (assembly, or some intermediate, like Java byte code) that we recognize as exception-handling, because in the end, the computer can execute only instructions; Everything of a higher-level must be comprised of those instructions.
In C, before exceptions existed, you would return an error code, but if a function already returns something, then what? Perhaps return a structure of both the error code and the real result?
The compiler outputs an athrow instruction (JVM Specification) at the throw site, and an Exceptions attribute (#4.7.5) in the code of the method that shows where all the various catch clauses are, what range of instructions they cover, and what exception types they catch.

What exception to throw?

I have a function which calculates the mean of a list passed as an argument. I would like to know which of Java exception should I throw when I try to compute the mean of a list of size 0.
public double mean (MyLinkedList<? extends Number> list)
{
if (list.isEmpty())
throw new ????????; //If I am not mistaken Java has some defined exception for this case
//code goes here
}
Thanks.
You can throw a new IllegalArgumentException().
Thrown to indicate that a method has been passed an illegal or inappropriate argument.
Just don't forget to pass a clear message as a first argument. This will really help you to understand what happend.
For example "Can't use mean on an empty List".
The question to ask yourself first is whether you should be throwing at all and then, if so, whether it should be a checked or unchecked exception.
Unfortunately, there's no industry best practice on deciding these things, as shown by this StackOverflow answer:
In Java, when should I create a checked exception, and when should it be a runtime exception?
Nevertheless, there are some key considerations:
Your design/vision for how this method is supposed to work (Is it reasonable/normal for the method to be called with 0-size list)?
Consistency with other methods in the class/package
Compliance with your applicable coding standard (if any)
My opinion:
Return Double.NAN or 0 If calling the method with a 0-size list is reasonable/expected/normal, I'd consider returning Double.NAN or 0 if 0 is appropriate for your problem domain.
Throw anIllegalArgumentException If my design says that checking for an empty List is strongly the responsibility of the caller and the documentation for the method is going to clearly state that it is the responsibility of the caller, then I'd use the standard unchecked IllegalArgumentException.
Throw a custom checked exception If the method is part of a statistics package or library where several statistics functions need to deal with an possible empty data set, I'd think this is an exception condition that is part of the problem domain. I'd create a custom (probably checked) exception (e.g. EmptyDataSetException) to be part of the class/package/library and use it across all applicable methods. Making it a checked exceptions helps remind the client to consider how to handle the condition.
You should create a new class that extends Exception and provides details specific to your error. For example you could create a class called EmptyListException that contains the details regarding your error. This could be a very simple exception class that takes no constructor arguments but maybe calls super("Cannot generate mean for an empty list"); to provide a custom message to the stack trace.
A lot of times this isn't done enough...one of my most hated code smells is when developers use a generic exception (even sometimes Exception itself) and pass a string message into the constructor. Doing this is valid but makes the jobs of those implementing your code much harder since they have to catch a generic exception when really only a few things could happen. Exceptions should have the same hierarchy as objects you use for data with each level providing more specific details. The more detailed the exception class, the more detailed and helpful the stack trace is.
I've found this site: Exceptional Strategies to be very useful when creating Exceptions for my applications.
IllegalArgumentException
How about NoSuchElementException. Although IllegalArgumentException might be better.
How about an ArithmeticException - the same as the runtime throws.
Are you currently throwing any other exceptions (or planning to?) Any of the previously mentioned exceptions are fine, or just create your own. The most important thing is propagating the message of what went wrong.
If there's a chance the 'catcher' of the exception might re-throw it, than you may want to investigate any other exceptions the 'catcher' might also throw.
I am not convinced you should be throwing an exception there at all; the average of "nothing" is "nothing" or 0 if you will. If the set is empty, you should simply return 0.
If you really MUST throw an exception, then IllegalStateException or IllegalArgumentException are your best choices.

Throws or try-catch

What is the general rule of thumb when deciding whether to add a throws clause to a method or using a try-catch?
From what I've read myself, the throws should be used when the caller has broken their end of the contract (passed object) and the try-catch should be used when an exception takes place during an operation that is being carried out inside the method. Is this correct? If so, what should be done on the callers side?
P.S: Searched through Google and SO but would like a clear answer on this one.
catch an exception only if you can handle it in a meaningful way
declare throwing the exception upward if it is to be handled by the consumer of the current method
throw exceptions if they are caused by the input parameters (but these are more often unchecked)
In general, a method should throw an exception to its caller when it can't handle the associated problem locally. E.g. if the method is supposed to read from a file with the given path, IOExceptions can't be handled locally in a sensible way. Same applies for invalid input, adding that my personal choice would be to throw an unchecked exception like IllegalArgumentException in this case.
And it should catch an exception from a called method it if:
it is something that can be handled locally (e.g. trying to convert an input string to a number, and if the conversion fails, it is entirely valid to return a default value instead),
or it should not be thrown (e.g. if the exception is coming from an implementation-specific lower layer, whose implementation details should not be visible to the caller — for example I don't want to show that my DAO uses Hibernate for persisting my entities, so I catch all HibernateExceptions locally and convert them into my own exception types).
Here's the way I use it:
Throws:
You just want the code to stop when
an error occurs.
Good with methods that are prone to
errors if certain prerequisites are
not met.
Try-Catch:
When you want to have the program
behave differently with different
errors.
Great if you want to provide
meaningful errors to end users.
I know a lot of people who always use Throws because it's cleaner, but there's just not nearly as much control.
My personnal rule of thumb for that is simple :
Can I handle it in a meaningful way (added from comment)? So put code in try/catch. By handle it, I mean be able to inform the user/recover from error or, in a broader sense, be able to understand how this exception affects the execution of my code.
Elsewhere, throw it away
Note : this replys is now a community wiki, feel free to add more info in.
The decision to add a try-catch or a throws clause to your methods depends on "how you want (or have) to handle your exception".
How to handle an exception is a wide and far from trivial question to answer. It involves specially the decision of where to handle the exception and what actions to implement within the catch block. In fact, how to handle an exception should be a global design decision.
So answering your questions, there is no rule of thumb.
You have to decide where you want to handle your exception and that decision is usually very specific to your domain and application requirements.
If the method where the exception got raised has a sufficent amount of information to deal with it then it should catch, generate useful information about what happened and what data was being processed.
A method should only throws an exception if it can make reasonable guarantees surrounding the state of the object, any parameters passed to the method, and any other objects the method acts upon. For example, a method which is supposed to retrieve from a collection an item which the caller expects to be contained therein might throws a checked exception if the item which was expected to exist in the collection, doesn't. A caller which catches that exception should expect that the collection does not contain the item in question.
Note that while Java will allow checked exceptions to bubble up through a method which is declared as throwing exceptions of the appropriate types, such usage should generally be considered an anti-pattern. Imagine, for example, that some method LookAtSky() is declared as calling FullMoonException, and is expected to throw it when the Moon is full; imagine further, that LookAtSky() calls ExamineJupiter(), which is also declared as throws FullMoonException. If a FullMoonException were thrown by ExamineJupiter(), and if LookAtSky() didn't catch it and either handle it or wrap it in some other exception type, the code which called LookAtSky would assume the exception was a result of Earth's moon being full; it would have no clue that one of Jupiter's moons might be the culprit.
Exceptions which a caller may expect to handle (including essentially all checked exceptions) should only be allowed to percolate up through a method if the exception will mean the same thing to the method's caller as it meant to the called method. If code calls a method which is declared as throwing some checked exception, but the caller isn't expecting it to ever throw that exception in practice (e.g. because it thinks it pre-validated method arguments), the checked exception should be caught and wrapped in some unchecked exception type. If the caller isn't expecting the exception to be thrown, the caller can't be expecting it to have any particular meaning.
When to use what. I searched a lot about this.
There is no hard and fast rule.
"But As a developer, Checked exceptions must be included in a throws clause of the method. This is necessary for the compiler to know which exceptions to check.
By convention, unchecked exceptions should not be included in a throws clause.
Including them is considered to be poor programming practice. The compiler treats them as comments, and does no checking on them."
Source : SCJP 6 book by Kathy Sierra
I ll make it simple for you.
Use throws when you think that the called method is not responsible for the exception (e.g., Invalid parameters from the caller method, item to be searched, fetched not available in the collections or fetch datalist).
Use try catch block(handle the exception in the called method) when you think that your functionality in the called method may result in some exception
If you use a try catch, when the exception occurs, the remaining codes would be still executed.
If you indicate the method to throw the exception, then when the exception occurs, the code would stop being executed right away.
try-catch pair is used when you want to provide customise behaviour, in case if exception occurs.....in other words...you have a solution of your problem (exception occurrence) as per your programme requirements.....
But throws is used when you don't have any specific solution regarding the exception occurrence case...you just don't want to get abnormal termination of your programme....
Hope it is correct :-)

Categories

Resources