Consider following example. Is it considered a bad practise?
Note: I know re-throwing exception is ok, but what about assertionerror?
public static main(){
try {
doSmth();
} catch (WhateverException we) {
throw new AssertionError(e.getMessage());
}
}
public static void doSmth() throws WhateverException { }
It's not bad practice to throw an error in response to an exception, if the exception indicates a situation that is fatal for your code. However:
There's no need to use AssertionError in particular. I mean, it's fine if you do, since nobody's going to be catching one, but you should consider just doing Error instead, so that somebody doesn't go looking for the assert statement that they assumed caused it.
When chaining a throwable like that, always use the old exception to construct the new one: throw new AssertionError(we). That'll keep the old stack trace around. You can (and should) also pass a custom message.
Related
So im reading the below and i understand why you would do it..
https://jenkov.com/tutorials/java-exception-handling/exception-wrapping.html
example :
try{
dao.readPerson();
} catch (SQLException sqlException) {
throw new MyException("error text", sqlException);
}
So what if i want to isolate all external exceptions inside the dao layer only, and only use my exceptions. so in the above example i dont want to send SQLEXception inside the constructor, would doing the below be enough. Would it contain enough information :
throw new MyException("error text", sqlException);
or maybe my constructor should be the following instead
public MyException(String text,Exception ex)
You can inherit your exception from Exception like
MyException extends Exception {
}
and then use try catch like :
try {
dao.readPerson();
} catch (MyException ex) {
// handle Exception
}
by doing this you can do whatever you want in your class and i think its cleaner than other ways.
It will trigger automatically so you dont need to raise an exception.
If you want to catch SQL Exceptions only you can inherit MyException from SqlException so it will only trigger when SqlException happens
I understand that you worry about the catching part of your code knowing about the wrapped exception. In "not knowing" there are different layers.
Level 1: Nothing obligates the catching class to get the cause and therefor explicitly knowing about the SQLException. They just catch the MyException and don't care what's wrapped in it. Usually that's enough.
Level 2. Another level of not knowing is restricting the catching class to even have access to the wrapped exception. In that case why wrap it at all? Just catch the SQLException in your DAO layer and throw MyException without wrapping the original exception in it.
About wrapping the causing Exception instead of the original one. You could do that but you might lose valuable information so 99% of the time it's not recommended. There are some corner cases where I've done it though. Let's say you throwing code runs asynchronously through ExecutorService. Then if an exception is thrown it's wrapped to ExecutionException, but as a caller I might not be interested that the code ran asynchronously so I catch the ExecutionException, get it's cause (the actual exception that happened) and wrap that to my custom exception.
I was playing with the Lombok library in Java and found an annotation called #SneakyThrows.
As the documentation states:
#SneakyThrows fakes out the compiler. In other words, Lombok doesn't wrap or replace the thrown checked exception, but makes the compiler think that it is an unchecked exception.
With other words, this is a way to bypass exceptions at compile time. But in my opinion this should not be the correct way of handling exceptions, because the bypassed exception can show weird behaviour at runtime.
So in which scenario should #SneakyThrows be used?
To add to the existing answers. I personally dislike checked exceptions. See for more info: https://phauer.com/2015/checked-exceptions-are-evil/
To add insult to injury, the code gets bloated when avoiding the checked exceptions. Consider the usage of #SneakyThrows:
List<Instant> instantsSneaky = List.of("2020-09-28T12:30:08.797481Z")
.stream()
.map(Example::parseSneaky)
.collect(Collectors.toList());
#SneakyThrows
private static Instant parseSneaky(String queryValue) {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(queryValue).toInstant();
}
versus non-#SneakyThrows
private static Instant parseNonSneaky(String queryValue) throws ParseException {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(queryValue).toInstant();
}
List<Instant> instantsNonSneaky = List.of("2020-09-28T12:30:08.797481Z")
.stream()
.map(timeStamp -> {
try {
return parseNonSneaky(timeStamp);
} catch (ParseException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
Hence the applicance of #SneakyThrows enables much cleaner code.
I believe the intention here is to cause the compiler to not require a throws whatever Exception to be added to the method declaration.
For example if the method was
public void throwsCheckedException() {
throw new IOException("IO exception thrown");
}
This would cause a compile time exception requiring
public void throwsCheckedException() throws IOException {
throw new IOException("IO exception thrown");
}
The annotation #SneakThrows mitigates this - original method declared as
#SneakyThrows
public void throwsCheckedException() {
throw new IOException("IO exception thrown");
}
This will not cause a compile time error.
Note IDEs might still highlight this as an error, for example in IntelliJ you will need to utilise the Lombok plugin.
I think the documentation is very clear on this:
Common use cases for when you want to opt out of the checked exception
mechanism center around 2 situations:
A needlessly strict interface, such as Runnable - whatever exception propagates out of your run() method, checked or not, it will
be passed to the Thread's unhandled exception handler. Catching a
checked exception and wrapping it in some sort of RuntimeException is
only obscuring the real cause of the issue.
An 'impossible' exception. For example, new String(someByteArray, "UTF-8"); declares that it can throw an UnsupportedEncodingException
but according to the JVM specification, UTF-8 must always be
available. An UnsupportedEncodingException here is about as likely as
a ClassNotFoundError when you use a String object, and you don't catch
those either!
In the JAVA 8 and above when using lambda especially its not an easy way to use.
Consider it mostly for older versions of Java 8.
The purpose itself is to throw an exception deliberately for example for warning. By this the other services/program/code can identify how the request/response flow should be handled. If you already have mechanism in place no need to worry about it.
#SneakyThrows is not of much use in current traditional application development, could be used in some kinda state machine programs where it would be necessary (i do not have expertise in it though) to determine the state of the programs current flow. This is just 1 example of different scenarios there maybe more.
I have an annotation on a method M in which I am making some checks, if the checks doesn't succeed I do not want to execute the underlying method M. I want the caller to know that the call didn't succeed along with the reason.
To achieve this I am throwing an exception out of annotation if checks fails. So here I have a couple of questions:
I am unable to catch the specific exception because the IDE tells me that exception is not being thrown out of the method?
For a quick hack I am catching Exception and then get to the specific Exception by using instance of operator.
Is there any other better way to achieve this?
Do I have a way in which I need not throw the exception?
Annotation aspect code looks something like this:
#Before(value = "#annotation(abc)", argNames = "pjp, abc")
public Object around(ProceedingJoinPoint pjp, ABC abc) throws Throwable {
if(notAllow()){
throw new CustomException("Not allowed");
} else {
pjp.proceed()
}
}
}
The handler code looks something like this:
catch(Exception e){
if(e instanceof CustomException){
// do something
}
}
The IDE can only verify checked exceptions. Make the exception extend RuntimeException.
You can catch that any time you want, because the IDE cannot verify if any code throws it, since methods are not required to declare if they do.
I have a bit of confusion in the following snippet.
try {
public static void showMyName(String str) throws IOException
{
if(str.equals("What is your Name?"))
throw new IOException;
}
}catch(IOException e)
{
System.out.println ("Exception occurs , catch block called")
}
Now, my question is what is difference between throws IOException && throw new IOException
Why don't we require to use catch , finally block for throws IOException ?
How does throws is handle the exception. ?
When an Exception is generated, there are two ways to deal with it.
Handle the Exception - this uses catch block
Declare the Exception - this uses throws block
So, dealing with an already generated exception is done by catch or throws.
On the other hand, throw is used while an Exception is "generated".
Typically, the throw keyword is used when you're instantiating an Exception object or while cascading an already generated exception to the caller.
For example,
public void doSomething(String name) throws SomeException { // Exception declared
if( name == null ){ // cause of the exception
throw new SomeException(); // actual NEW exception object instantiated and thrown
}
// Do something here
.
.
.
}
In the calling method,
public static void main(String[] args) throws SomeException{ // Need to declare exception because you're "throwing" it from inside this method.
try { // try doing some thing that may possibly fail
doSomething(name);
} catch (SomeException e){
throw e;// throw the exception object generated in doSomething()
}
}
Alternately, you can "handle" the exception in the catch block:
public static void main(String[] args) { // No need to declare exception
try { // try doing some thing that may possibly fail
doSomething(name);
} catch (SomeException e){
System.out.println("Exception occurred " + e.getMessage()); // Handle the exception by notifying the user.
}
}
Hope this helps.
Addendum - Exception Handling glossary
try - used for invoking code that can potentially cause exceptions or with resources such as Files/Streams/Network/Database connections.
catch - used immediately after a try block to "handle" or "throw" exceptions. Optional if finally is used.
finally - used immediately after a try or catch block. Optional. Used for executing code that "must" be executed. Code within a finally block always gets executed - even if the try or catch has a return statement.
throw - used to "push" or "cascade" exceptions through the calling methods. Always used inside a method.
throws - used to "declare" that a method will be throwing an exception if something goes wrong. Always used as part of method signature.
Addional Reading
Here's an elaborate article to help you understand the try-catch-finally semantics in java.
Update
To answer your other question,
Why don't we require to use catch , finally block for throws
IOException ?
Think of catch and throws as mutually exclusive constructs. (This is not always true, but for your understanding, it's good to start with this thought.)
You declare a method that it throws IOException. This piece of code is written at a point where you declare the method. And, syntactically, you cannot place a method declaration inside a try block.
How does throws is handle the exception. ?
Like I mentioned before, catch and finally are used during exception handling. throws is just used to cascade the exception back to the caller.
throw new IOException means that you encountered some error condition and decided to break the flow of the program by throwing an exception.
If that exception is a checked exception (i.e. not Error or RuntimeException), you must either catch that exception in a catch block, or declare in the method's signature that the method is expected to throw that exception (or a super-class of that exception). That's what the throws IOException means.
You are pretty much right on. Except for one thing I'll mention in a bit.
throws is as much a part of the method API as the name and the parameters. Clients know if they call that method, they need to handle that exception--by simply throwing it also or by catching it and handling it (which may in fact entail the throwing of another exception wrapping the original). throws is addressed at compile time.
throw is the actual act of letting the runtime know something bad happened--that the exceptional condition we were worried about has in fact taken place. So it needs to be dealt with at runtime.
But you weren't quite right when you said, "Throws in method signature should always appear if there exist a throw statement in the method." That is often true but not always. I could also call another method that throws an exception within my method, and if I don't catch it, my method needs to throw it. In that case, there is no explicit throw of the same exception by me.
The final point is that you only need to declare an exception in throws when the exception is a checked exception--meaning it is from the other side of the Exception class hierarchy from RuntimeException. Common checked exceptions are IOException and SQLException. Checked exceptions must be listed in the throws part of the method signature if you don't handle them yourself. Anything subclassing RuntimeException--like NoSuchElementException in your example and also the hated NullPointerException--is an unchecked exception and doesn't have to be caught or thrown or anything.
Typically, you use checked exceptions for recoverable problems (where the client knows what can happen and can gracefully handle the problem and move on) and unchecked exceptions for catastrophic problems (like can't connect to the database).
If you can get past all the AOP stuff, this is a great discussion of how you use checked and unchecked exceptions effectively.
The first biggest difference is throw can throw exception like you throw stone in river,
and throws state that this method have chances to throw exception but may not also... and thats why throws dont need try catch because it state already that it gona throw some kind of exception.
throws keyword means that this method will throw any Exception that will have to be handled in a higher level.
public static void showMyName(String str) throws IOException
If another method call this method, it has to catch this exception or throw it one more time (by typing throws in its signature).
Catch the exception or keep throwing it, depends on your business logic.
I'm reading exception handling in the book "A programmer guide to Java SCJP certificate". The author wrote that :
If a checked exception is thrown in a method, it must be handled in one of three ways:
1.By using a try block and catching the exception in a handler and dealing with it
2.By using a try block and catching the exception in a handler, but throwing
another exception that is either unchecked or declared in its throws clause
3.By explicitly allowing propagation of the exception to its caller by declaring it
in the throws clause of its method header
I understood clearly the first and third, but the second made me a lot of confused. My concerns are that :
-It's still alright even if I don't throw any other unchecked exceptions, so why do we have to throw another exception at here?
-Why do we have to re-declare the exception that we have caught, in throws clause? I think it's over by the handler.
Thanks to everyone.
The book just list three allowed options.
-It's still alright even if I don't throw any other unchecked exceptions,
so why do we have to throw another
exception at here?
You might want to throw another more descriptive exception, for example adding more info.
-Why do we have to re-declare the exception that we have caught, in
throws clause? I think it's over by
the handler.
You don't have to re-declare. But if the new exception you are throwing is checked, then you must declare it in the throws clause. In fact the exception you just caught doesn't need to be declared even if checked.
You may want to do this to catch a checked exception and throw another checked exception of a different kind. Perhaps you want to throw your own exception rather than a different one.
public void doSomething() throws MyCheckedException {
try {
doSomethingThatThrowsSpecificCheckedException();
} catch(SpecificCheckedException e) {
throw new MyCheckedException();
}
}
Or you can throw an unchecked exception (something that is or extends RuntimeException).
public void doSomething() {
try {
doSomethingThatThrowsSpecificCheckedException();
} catch(SpecificCheckedException e) {
throw new RuntimeException();
}
}
First of all, you should declare in the throw clause the exception that you throw, not the one you caught, assuming you are throwing a checked exception.
Second, you don't have to do that. It is just one of the three options.
Why would you do that? Usually this is done between the application layers. For example, Hibernate catches SQLExceptions and rethrows them as unchecked HibernateException, so that code that calls Hibernate methods doesn't have to be polluted with the try/catches for SQLExceptions. Another option is to translate a low-level exception into some business logic exception that can be handled up the stack. This allows for the better isolation of the business logic from the low level implementation details.
Great question, and one which good java programmers should get their head around.
It's all about adhering to the method signature that defines the method's contract with its caller, and which includes what exceptions you are going to throw.
Option 1 is dealing with the exception
Option 2 is not dealing with the exception, but keeping the same contract
Option 3 is not dealing with the exception and changing your contract
A implementation of the pattern in option 2 would be:
public interface Server {
public void useServer() throws ServerException;
}
public class ExplodingClient {
private Server server = new ServerImpl();
public void doIt() throws ClientException {
try {
server.useServer();
} catch (ServerException e) {
// Our contract doesn't allow throwing ServerException,
// so wrap it in an exception we are allowed by contract to throw
throw new ClientException(e);
}
}
}
public class SilentClient {
private Server server = new ServerImpl();
public void doIt() {
try {
server.useServer();
} catch (ServerException e) {
// Our contract doesn't allow throwing any Exceptions,
// so wrap it in a RuntimeException
throw new RuntimeException(e);
}
}
}
By using a try block and catching the
exception in a handler, but throwing
another exception that is either
unchecked or declared in its throws
clause.
Handling the exception in Java can be done in two ways :
Wrapping it in try-catch-finally block.
Declaring the method to throw ( using throws) the exception to the caller of method to handle.
-It's still alright even if I don't throw any other unchecked exceptions,
so why do we have to throw another
exception at here?
Throwing another exception means describing more about it. Also, to let the caller of the method know that this particular exception was generated.
-Why do we have to re-declare the exception that we have caught, in
throws clause? I think it's over by
the handler.
Redeclaring exception that you just caught in the catch block is to make the caller of this method alert that this method could throw a particluar exception. So be prepare to handle it.
You must go over this Jon Skeet's post : Sheer Evil: Rethrowing exceptions in Java
Remember, you are never forced to handle the unchecked exceptions, compiler forces you to just catch the checked one.