public void onClick() throws SQLException
try {
// Do something
} catch(MySQLIntegrityConstraintViolationException e) {
//Can i convert this exception to SQL Exception
}
Can i convert MySQLIntegrityConstraintViolationException to SQLException which is thrown by the method?
But the MySQLIntegrityConstraintViolationException already is a SQLExecption (through inheritence)! So there's no need to rethrow it (just remove the try/catch-block).
Sure you can wrap and rethrow - if you think it adds more information or makes your ideas more general. I think in this case the exception you're catching gives more info than the one you're thinking about.
I wouldn't choose a SQLException, though. It's a checked exception. I think the tide has turned from checked to unchecked exceptions.
Spring wraps SQLExceptions into unchecked DataAccessException that extends RuntimeException. I'd suggest that you follow suit.
Here's how you should do it:
catch(MySQLIntegrityConstraintViolationException e) {
throw new SQLException(e);
}
Don't just pass the message. Give the whole stack trace.
You can use the construtor of SQLException to create one in your Catch Block..
try {
} catch (MySQLIntegrityConstraintViolationException e) {
throw new SQLException(e);
}
Since MySQLIntegrityConstraintViolationException is subclass of SQLException re throwing is unnecessary. If you want to abstract your business logic layer from database specific details, make sure to catch SQL Exceptions in the logic layer so that even if the database is switched logic would still valid.
Related
Sometimes I would want to throw an exception with more information to the user, so they can easily see why the method failed.
My method would look like this:
public myPublicMethod(...) throws Exception1, Exception2 {
try {
doSomething(); // this throws OtherException
}
catch (OtherException e) {
Exception cause = e.getCause()
if (cause instanceof Exception1) {
throw (Exception1) cause;
}
if (cause instanceof Exception2) {
throw (Exception2) cause;
}
throw new IllegalStateException("some other type of exception occurred", cause);
}
}
Is this design acceptable?
Your thinking is good, however in my humble opinion the way you implemented it is kind of missing the point, I'll try to explain.
You started with the claim that you want to give the user more information about the exception. What you did - striping the cause from its "parent exception" (e.getCause() and then throwing the cause) - actually gives the user less information, since the information in OtherException, that you discarded, might contain useful details about the flow caused the program to crash.
It is a good practice to catch the most specific exception and throw it to the caller, but make sure that you're not omitting details. Throwing the cause without the parent exception is actually omitting details.
It makes sense sometimes to wrap an exception that you caught and provide more details about it (like you intended to do in your last line), but again - make sure that you're only adding details, and not omitting details.
You can read more about exceptions handling best practices here.
I would want to throw an exception with more information
There's nothing wrong with the practice of catching an exception in order to provide additional information by wrapping it with a custom or built-in exception and re-throwing.
I think it's if you want to do it only for a limited number of types of exceptions by wrapping with the IllegalStateException and adding a custom message and preserving the cause of exception. But there's a caveat: a type of OtherException shouldn't be too broad, like general Exception, so that it will encompass only a limited number of exceptions types.
But re-throwing the only a cause like you've done for Exception1 or Exception2 looks suspicious. For some reason, you don't consider them to be the root-cases and going to blind on the information they could carry. It sounds like a design flaw. Also keep in mind that cause could be null (in this case, exception doesn't wrap anything) and this code will fail with NullPointerException. Therefore, in the in example below, the same exception will get re-thrown instead of re-throwing the cause.
From the clean-coding perspective, it's better to use as fewer type-checks as possible. And I think in this case you don't need to resort to instanceof check.
Instead, you can utilize the features that exception handling mechanism provides.
Since you need to perform the same action (re-throw the exception that was caught) if Exception1 or Exception2 occurs, if types Exception1 or Exception2 are siblings (i.e. they don't extend each other), these exceptions can be handled with a multi-catch clause to avoid code duplication:
catch (Exception1 | Exception2 e) {
throw e;
}
Otherwise, if let's say Exception2 is a subtype of Exception1 then you should handle them in the separate catch blocks starting from more specific type, i.e. subtype should be handled before supertype:
catch (Exception2 e) {
throw e;
}
catch(Exception1 e) {
throw e;
}
And after that add a catch clause with the least specific type (more wide than all exception types defined previously), to handle all other exception types that might take place by throwing a new instance of IllegalStateException.
Example:
public void myPublicMethod(Path source, Path destination)
throws FileAlreadyExistsException, DirectoryNotEmptyException {
try {
Files.copy(source, destination);
// do some other actions
}
catch (FileAlreadyExistsException | DirectoryNotEmptyException e) {
throw e;
}
catch (IOException e) {
throw new IllegalStateException("some other type of exception occurred", e);
}
}
In IntelliJ I'm working on some code that retrieves entities from Google Cloud DataStore, using a try catch block like this:
try {
T dataAccessObject = class.newInstance();
entity = datastore.get(KeyFactory.createKey(dataAccessObject.GetEntityName().toString(), id));
dataModel = (T)dataAccessObject.ToModel(entity);
return dataModel;
} catch (EntityNotFoundException e) {
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
}
To me, the empty catch statement for the EntityNotFoundException is a code smell, and I'd rather remove it and allow the exception to be thrown.
When I remove that catch statement however, it causes a compiler error, and I'm not seeing any explanation or rationale as to why removing the statement is invalid.
The datastore.get is calling something that implements the com.google.appengine.api.datastore.DatastoreService interface, which means it's possible for an EntityNotFoundException to be thrown, which can be seen if we look at the constructor as defined in the interface:
com.google.appengine.api.datastore.DatastoreService
public interface DatastoreService extends BaseDatastoreService {
Entity get(Key var1) throws EntityNotFoundException;
Why would I need to catch the exception though? Why do I get the compile error?
Java has two different kinds of exceptions: checked and unchecked.
Checked Exceptions:
Any java.lang.Throwable that does not extend from java.lang.Error or java.lang.RuntimeException.
Must be explicitly handled where they can be thrown. Not doing so results in a compilation error. A checked exception is handled if it is caught in a try-catch block or if the containing method is declared to throws the checked exception.
Unchecked Exceptions:
Any instance of java.lang.Error or java.lang.RuntimeException.
Can be caught and handled, but doesn't need to be. Can also be used in the throws clause of a method signature but doing so is typically considered bad practice. If one wants to document the possibility of an unchecked exception being thrown by a method they should do so in the Javadoc, via #throws.
Based on the compilation error, I can only assume EntityNotFoundException is a checked exception and thus must be handled. For more information, see Java: checked vs unchecked exception explanation.
I agree that an empty catch block is smelly. At the very least, you should log the exception. If you end up doing the same thing for each possible exception, you could rewrite the try-catch like so:
try {
/* Do stuff... */
} catch (EntityNotFoundException | IntantiationException | IllegalAccessException ex) {
// log ex...
}
The above syntax requires Java 7+, I believe.
Lately, I have been seeing a lot of (commercial) code that throws and catches the exact same exception, similar to the code below:
public class Foo {
public void bar() throws AnException {
// do something (1)
try {
// do something (2) -- able to throw AnException
} catch (AnException ex) {
throw ex;
}
// do something (3)
}
}
Contrast this to:
public class Foo {
public void bar() throws AnException {
// do something (1)
// do something (2) -- able to throw AnException
// do something (3)
}
}
Does the former actually accomplish anything, in either behavior or semantics or else? Will it have any effect on code performance (time and space) or does it help readability?
P.S. this question is very different from this question.
EDIT: The catch block in the former doesn't do anything else other than rethrowing the caught exception.
This is a violation of a basic rule:
The code should catch only the exceptions that it knows how to handle.
Oracle's guidelines suggests that each time you throw an exception, you should supply something useful for the code that catches your exception (see page 3 of Effective Java Exceptions). Catching an exception simply to re-throw it serves no practical purpose, because there is no additional information added to it for the code above it in the invocation chain, and no information extracted by the method itself.
It makes no sense for sure assuming code you provided.
Rethrowing exceptions makes sense when you want to handle this exception somehow (e.g. log it) but want it to be handled further in a stack trace.
Regarding commercial code, maybe the reason you saw it was that there was some handling logic initially that was removed but exceptions rethrowing wasn't removed. I saw such situations several times.
There's no reason for the try/catch in the code you posted. As with #nickolay.laptev's answer, I believe that if you find this in commercial code, it's probably left over cruft from something that used to be meaningful.
Aside from some sort of partial error handling, there's another use case for simply catching and rethrowing an exception. This would be to prevent the exception from being caught by a subsequent, more general, catch clause. So, for instance, if you wanted to handle every exception other than instances of AnException, you would either have to do a type check:
try {
// stuff
} catch (Exception ex) {
if (ex instanceof AnException) {
throw ex; // rethrow since we're not handling it
} else {
// handle all other exceptions
}
}
or use something like this (which, in my view, is cleaner and more readable):
try {
// stuff
} catch (AnException) {
throw ex;
} catch (Exception ex) {
// handle all other exceptions
}
Then if you later decided to not handle all those other exceptions, you'd delete the second catch clause and end up with the code you posted.
I was wondering if there was a way to write a catch statement that is activated whenever any exception is thrown in a program. Thanks!
The problem with the answers you have received so far is that if you include a "catch-all" in your main, it will only catch exceptions thrown on the main thread.
A more robust way to catch all uncaught exceptions is to setup a DefaultUncaughtExceptionHandler for your project, for example, at the start of your main, you can call:
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
//log the exception
}
});
Note that it is generally unreasonable to do anything but logging in there, as the Throwable could be anything, including unrecoverable errors.
You can make the type Exception. That will catch any Exception, but it also doesn't give the programmer much information on what went wrong. It's usually better to try to be more specific about the type of exception that has occurred, mainly for semantic reasons.
The theory
Every type of Java Exception extends the Exception type. Because Exception is a superclass of all exceptions, when an exception is thrown, regardless of it's type, it can still be implicitly casted to an object of type Exception.
Edit
As mentioned in the comments, there is also type Error that can be thrown, so to really catch everything using the Throwable type is best. Throwable is more general than Exception, but it still works on the exact same principle. It is the superclass of anything that can be thrown.
For Example
try{
// Some code
}
catch(Throwable e)
{
// Do something. Edited due to comment!
}
To catch all exceptions some block of code may throw you can do: (This will also catch Exceptions you wrote yourself)
From How can I catch all the exceptions that will be thrown through reading and writing a file?
try {
// exceptional block of code ...
// ...
} catch (Exception e){
// Deal with e as you please.
//e may be any type of exception at all.
}
The reason that works is because Exception is the base class for all runtime exceptions. Thus any runtime exception that may get thrown is an Exception.
The is because all runtime exceptions inherit from Exception. Note that there is a difference between an Error and Exception Unchecked exceptions in Java: Inherit from Error or RuntimeException?, In that case you may need to do:
try {
} catch(Throwable e) {
}
See this When should Throwable be used instead of new Exception?. One user notes:
Error is programmatically unrecoverable in any way and is usually not to be caught, except for logging purposes (which passes it through again). Exception is programmatically recoverable. Its subclass RuntimeException indicates a programming error and is usually not to be catched as well. See comments for additional information.
Yes, any error that falls through will be caught by this:
try {
//do things here
} catch (Exception e) {
//handle exception here
}
Note, however, that it's typically the wrong thing to do.
In your main, put all your code in
try {
//Your code
} catch(Exception e) {
//Handle exceptions
}
This will handle any exception invoked by your code.
What is the difference between try-catch and throw clause. When to use these?
Please let me know .
The try block will execute a sensitive code which can throw exceptions
The catch block will be used whenever an exception (of the type caught) is thrown in the try block
The finally block is called in every case after the try/catch blocks. Even if the exception isn't caught or if your previous blocks break the execution flow.
The throw keyword will allow you to throw an exception (which will break the execution flow and can be caught in a catch block).
The throws keyword in the method prototype is used to specify that your method might throw exceptions of the specified type. It's useful when you have checked exception (exception that you have to handle) that you don't want to catch in your current method.
Resources :
oracle.com - Lesson: Exceptions
On another note, you should really accept some answers. If anyone encounter the same problems as you and find your questions, he/she will be happy to directly see the right answer to the question.
If you execute the following example, you will know the difference between a Throw and a Catch block.
In general terms:
The catch block will handle the Exception
throws will pass the error to his caller.
In the following example, the error occurs in the throwsMethod() but it is handled in the catchMethod().
public class CatchThrow {
private static void throwsMethod() throws NumberFormatException {
String intNumber = "5A";
Integer.parseInt(intNumber);
}
private static void catchMethod() {
try {
throwsMethod();
} catch (NumberFormatException e) {
System.out.println("Convertion Error");
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
catchMethod();
}
}
Try/catch and throw clause are for different purposes. So they are not alternative to each other but they are complementary.
If you have throw some checked exception in your code, it should be inside some try/catch in codes calling hierarchy.
Conversely, you need try/catch block only if there is some throw clause inside the code (your code or the API call) that throws checked exception.
Sometimes, you may want to throw exception if particular condition occurred which you want to handle in calling code block and in some cases handle some exception catch block and throw a same or different exception again to handle in calling block.
All these keywords try, catch and throw are related to the exception handling concept in java. An exception is an event that occurs during the execution of programs. Exception disrupts the normal flow of an application. Exception handling is a mechanism used to handle the exception so that the normal flow of application can be maintained. Try-catch block is used to handle the exception. In a try block, we write the code which may throw an exception and in catch block we write code to handle that exception. Throw keyword is used to explicitly throw an exception. Generally, throw keyword is used to throw user defined exceptions.
For more detail visit Java tutorial for beginners.
Others have already given thorough answers, but if you're looking for even more information, the Oracle Java tutorials are always a good resource. Here's the Java tutorial for Exceptions, which covers all of your questions in great detail; https://docs.oracle.com/javase/tutorial/essential/exceptions/index.html
try block contains set of statements where an exception can occur.
catch block will be used to used to handle the exception that occur with in try block. A try block is always followed by a catch block and we can have multiple catch blocks.
finally block is executed after catch block. We basically use it to put some common code when there are multiple catch blocks. Even if there is an exception or not finally block gets executed.
throw keyword will allow you to throw an exception and it is used to transfer control from try block to catch block.
throws keyword is used for exception handling without try & catch block. It specifies the exceptions that a method can throw to the caller and does not handle itself.
// Java program to demonstrate working of throws, throw, try, catch and finally.
public class MyExample {
static void myMethod() throws IllegalAccessException
{
System.out.println("Inside myMethod().");
throw new IllegalAccessException("demo");
}
// This is a caller function
public static void main(String args[])
{
try {
myMethod();
}
catch (IllegalAccessException e) {
System.out.println("exception caught in main method.");
}
finally(){
System.out.println("I am in final block.");
}
}
}
Output:
Inside myMethod().
exception caught in main method.
I am in final block.
In my limited experience with the following details.throws is a declaration that declares multiple exceptions that may occur but do not necessarily occur,
throw is an action that can throw only one exception, typically a non-runtime exception,
try catch is a block that catches exceptions that can be handled when an exception occurs in a method,this exception can be thrown.An exception can be understood as a responsibility that should be taken care of by the behavior that caused the exception, rather than by its upper callers.
I hope my answer will help you
try - Add sensitive code
catch - to handle exception
finally - always executed whether exception caught or not. Associated with try -catch. Used to close the resource which we opened in try block
throw - To handover our created exception to JVM manually. Used to throw customized exception
throws - To delegate the responsibility of exception handling to caller method or main method.