Related
I am writing some exception handling for one of projects where I had to throw exceptions depending on the error code inside a catch block. I have done it in the below way:
public BankStatistics fetchBankStatistics(final Customer id) {
final BankStatistics bs= this.bankStatService.fetchStatDetails(id);
return bs;
} catch (final StaticticsProcessingexception ex) {
if (ex.getErrorCode().equals("STAT-102")) {
// log the error
throw new MyNewCustomException(ERROR.INVALID_CUST_ID)
}
if (ex.getErrorCode().equals("STAT-103")) {
// log the error
throw new MyNewCustomException(ERROR.CUST_DOES_NOT_EXIST)
}
if (ex.getErrorCode().equals("STAT-104")) {
// log the error
throw new MyNewCustomException(ERROR.CUST_NOT_AUTHENTICATED)
}
return null;
}
The above code compiles, but I somehow did not like the idea of returning the null from the catch block. If you can give some suggestions if the above code is the best way to handle this scenario or is there any other way too?
I provide below my view in this case. I would suggest to main a Map of error code as key and other details as values. For example you can maintain like this.
Map<String,String> errMap = new HashMap<>();
errMap.put("STAT-102",ERROR.INVALID_CUST_ID);
errMap.put("STAT-103",ERROR.CUST_DOES_NOT_EXIST);
errMap.put("STAT-104",ERROR.CUST_NOT_AUTHENTICATED);
The benefit here is there is no need to write multiple if in the exception block, you can simply write like this.
catch (final StaticticsProcessingexception ex) {
throw new MyNewCustomException(errMap.get(ex.getErrorCode()))
}
As Kayman Sir suggested, you can also throw IllegalArgumentException, besides based uupon your business requirements, you can also create your own exception class and you can throw it by handling the error.
Why don`t you just throw ex in this case?
You may throw YourNewCustomException with null message.
throw new MyNewCustomException();
I'm a beginner in java writing an frontend for a webservice.I have to validate the input to get useful error messages for the user.Currently it works this way:
public Object zipVal(String zip)
{
try
{
if (zip.length() == 5)
{
val.setZip(Integer.parseInt(zip));
return val.getZip();
} else
{
return lengthError;
}
} catch (NumberFormatException e)
{
return formatError;
}
}
for zip Codes.Using Objects to declare the return type is not what I want tho(and is afaik discouraged),but I'm not sure how I should handle wrong inputs other than that.Should I just return null for every Exception and invalid input and handle such things in another method?
Edit:Added something to actually throw an Exception...
Yeah, exception handling might be one of the trickier things to consider (if one comes from a C programming background for example, where we used to be happy with < 0 return code for indicating erroneous program flow).
Normally you are pretty safe off by catching other API:s you integrate with and encapsulate them in your own exception (sort of masking them away), but by doing so don't forget to chain the original exception into your own with this constructor (and/or derivatives of such):
public MyException(final String message, final Throwable cause) {
super(message, cause);
}
One surely see alot of:
catch (Exception) {
return null;
}
and such in code as well, I wouldn't say that this is "good" object orientation, but it is still common and could be used in special occasions.
And also, its usually very important what you do (how to handle) when you catch the exception, someone told me that programing is 90% about error control and 10% about functionality :)
Here are some tutorials/resources:
http://docs.oracle.com/javase/tutorial/essential/exceptions/
http://howtodoinjava.com/2013/04/04/java-exception-handling-best-practices/
If you are returning a value, then there is no need to handle the exception. It is better you declare that the method may throw the exception.
NumberFormatException is a RunTimeException. So if you wish to handle it, then better return an invalid zip (say -1) to let the caller know that something went wrong.
Otherwise, declare that you will throw a Custom Exception if NFE occurs.
This snippet may be useful.
public int setZipVal(String zip) // throws CustomException
{
try
{
if (zip.length() == 5)
{
val.setZip(Integer.parseInt(zip));
return val.getZip();
}
} catch (NumberFormatException e)
{
// Log the error and return invalid zip
return -1;
// OR throw custom exception
throw new CustomException("Length Error"));
}
}
I'm a relative newbie to custom error handling in Java, and I'm trying to figure out how to use catch statements to deliver specific messages inside of an if statement. I wanted to get some extra sets of eyes to look at what I'm trying to do and offer feedback before I completely overthink this and overdo it too badly.
Consider:
We have a directory of hourly log files and I have an on-demand reporting job creates a concatenation of all today's log files created so far. I want to add a step that checks for the existence of a concatenated log file, deletes it then creates it if present, or just creates it if it's not present. With the code below, I'm returning an exception if, for some reason, the new file cannot be created.
try {
File file = new File (destinationPath + "todayToNowLogFile.csv");
if(file.exists())
{
if(file.delete())
{
System.out.println(file.getName() + " is deleted!");
} else {
System.out.println("Existing file cannot be deleted.")
}
} else {
System.out.println("File will be created.");
}
}
//
catch(Exception e) {
System.err.println("Exception: ");
System.out.println("Exception: "+ e.getMessage().getClass().getName());
e.printStackTrace();
}
Now, in the case where the file cannot be deleted, I would like to display the exception preventing file deletion. First, I would need to catch that error, but then where do I put the try?
Doing something like this...
try
{
if(file.delete())
{
System.out.println(file.getName() + " is deleted!");
}
}
else {
catch(Exception eDel) {
System.err.println("Exception: ");
System.out.println("Exception: "+ eDel.getMessage().getClass().getName());
eDel.printStackTrace();
}
}
....interrupts the if...then block. I'm not sure how to insert a try...catch within an if...then. Is there a way to do this? Or does my original code catch EVERY error associated with ANY operation on the file defined in the try block, and I would need to put if...then logic in the catch block, something along the lines of this pseudocode....
catch(Exception e) {
if(exception relates to file deletion) {
"File delete exception " + exceptionMessages;
} else if(exception relates to file creation) {
"File create exception " + exceptionMessages;
} else if(other exception) {
"other exception " + exceptionMessage;
} else {
"no exceptions encountered"
}
}
What's the most appropriate way to handle this type of situation?
You should think of try/catch as any other statement. So you can put it inside any of two branches of if/then/else statement, but it have to be whole inside:
if(statement){
...
try{
...
}catch(...){
...
}
...
}else{
...
try{
...
}catch(...){
...
}
...
}
If you have to catch multiple exceptions you can achieve this by multiple catch parts:
try{
...
}catch(Exception1 e1){
...
}catch(Exception2 e2){
...
}catch(Exception3 e3){
...
}
What you want here is to create your own Exception class.
To create an exception class say you need to extend Exception class. Here's an example.
Lets say my custom exception class should be named as MyFileErrorException
So I create a new class like this -
class MyFileErrorException extends Exception {
private String message = null;
public MyFileErrorException() {
super();
}
public MyFileErrorException(String message) {
super(message);
this.message = message;
}
public MyFileErrorException(Throwable cause) {
super(cause);
}
#Override
public String toString() {
return message;
}
#Override
public String getMessage() {
return message;
}
}
Now I need to throw this exception at will. So in Your case you wantto catch File delete exception so the code will like this -
if(file.delete())
{
System.out.println(file.getName() + " is deleted!");
} else {
try{
System.out.println("Existing file cannot be deleted.")
throw new MyFileErrorException("File Could not be deleted val is null");
}catch(MyFileErrorException ex){
//Do wahtever you want to do
}
}
At first you should check if any method could throw any specific Exceptions. You could do this by looking into the Javadoc or use your favorite IDE.
If you catch Exception as the Exception class, it catches every Exception that is subclass of it.
If you want to have specific Exception handling, e.g. for an IOException like in the delete() method, you can catch every specific Exceptionclass or use multi-catch in Java 7
try {
do regular code that can throw exceptions
} catch(Exception e) {
it catches every Exception that is a subclass of Exception.
You handle every exception raised in the try block above by the same way
}
If you want to handle exceptions in different ways, e.g. print different messages, just do this like the following example:
try {
do sth
} catch (SpecificExceptionclass sec) {
do sth specific for this exception
} catch (AnotherExceptionClass aec) {
do sth else
}
Or just use Multicatch in Java 7, if you want to have same exception handling for some specific exception classes:
try {
do sth
} catch (SpecificExceptionclass | AnotherExceptionClass e) {
do sth specific for this exception
}
To achieve different Exceptions thrown in your code the methods should at least throw different exceptions. In your example with file.exists() and file.delete() there's only an IOException thrown by your code, so there is no use of specific exception handling.
I think it would be a good idea to put your code in a function that returns true or false.
1: True means the file does not exist and was created
2: False means the file exists and was deleted.
3: An exception if the file exists but cant be deleted.
Also provide a separate function to determine if the file exists or not.
Your javadoc at the top of your functions should explain the above so the caller of your functions don't have to look at their content to determine how to use them.
Note an exception is an unusual event and shouldn't be thrown to indicate the state of inserting/deleting. It should be reserved for unusual conditions which the caller normally wouldn't encounter.
A note on exceptions: If you have a large project with 1000 classes each of which has on average 20 functions, that's 20000 functions. Its not practical to pepper each function with excessive exception handling (such as checking for nulls passed in as arguments). A solution to this is to handle checked exceptions in the java language (FileIO) and let (the bulk) of unchecked exceptions ripple up the function call chain until you leave all your business logic and are about to display the results. You only catch them if you want to add additional information to the exception before rethrowing it. Example: adding the primary key value of the record of an SQLExeption being thrown so you know what record is causing problems. Just before you return to the user, log the stack trace and display a simplified message to the user (not the stack trace). The caller of your function should read its javadoc to see how to use it. If he violates your javadoc, the function may or may not throw an exception. Its his reponsibility to follow the javadoc. Last point: your project should have general coding policies for the entire project to prevent some types of exceptions from accidently being introduced by the caller such as: all functions are not epected to recieve nulls as arguments or will return a null unless specified in its javadoc. All functions will accept as arguments (or return) empty lists or empty strings correctly unless specified in their javadoc.
Which one will be better: ErrorCode or Exception for that situation?
I have ever been seeing these two error handling techniques. I don't know the disadvantages and advantages for each technique.
public void doOperation(Data data) throws MyException {
try {
// do DB operation
} catch (SQLException e) {
/* It can be ChildRecordFoundException, ParentRecordNotFoundException
* NullValueFoundException, DuplicateException, etc..
*/
throw translateException(e);
}
}
or
public void doOperation(Data data) throws MyException {
try {
// do DB operation
} catch (SQLException e) {
/* It can be "CHILD_RECORD_FOUND, "PARENT_RECORD_NOT_FOUND"
* "NULL_VALUE_FOUND", "DUPLICATE_VALUE_FOUND", etc..
*/
String errorCode = getErrorCode(e);
MyException exc = new MyException();
exc.setErrorCode(errorCode);
throw exc;
}
}
For second method, the error code retrieve form configuration file. We can add Error Code based on the SQL Vender Code.
SQL_ERROR_CODE.properties
#MySQL Database
1062=DUPLICATE_KEY_FOUND
1216=CHILD_RECORD_FOUND
1217=PARENT_RECORD_NOT_FOUND
1048=NULL_VALUE_FOUND
1205=RECORD_HAS_BEEN_LOCKED
Caller client for method 1
try {
} catch(MyException e) {
if(e instanceof ChildRecordFoundException) {
showMessage(...);
} else if(e instanceof ParentRecordNotFoundException) {
showMessage(...);
} else if(e instanceof NullValueFoundException) {
showMessage(...);
} else if(e instanceof DuplicateException) {
showMessage(...);
}
}
Caller client for method 2
try {
} catch(MyException e) {
if(e.getErrorCode().equals("CHILD_RECORD_FOUND")) {
showMessage(...);
} else if(e.getErrorCode().equals("PARENT_RECORD_NOT_FOUND") {
showMessage(...);
} else if(e.getErrorCode().equals("NULL_VALUE_FOUND") {
showMessage(...);
} else if(e.getErrorCode().equals("DUPLICATE_VALUE_FOUND") {
showMessage(...);
}
}
I recommend using Spring's JDBCTemplate. It will translate most existing databases' exceptions into unchecked exceptions that are specific, e.g. DataIntegrityViolationException. It will also include the original SQL error in the message.
Strange question, since both approaches do the same thing: they transform a checked SqlException in a different exception which seems to be unchecked. So the first one is the better one because it moves this into a single method.
Both leave some questions to be asked:
Isn't there some infrastructure that can do this conversion (Spring Template was mentioned in another answer)
Do you really want checked Exceptions, in my mind they are hardly ever worth the trouble.
Who is doing the real handling of the exception, does it get all the information needed? I would normaly expect some additional information about the transaction that failed inside of MyException, like: What did we try to do? (e.g. update a busines object); On what kind of object? (e.g. a Person); How can we/the user Identify the object (e.g. person.id + person.lastname + person.firstname). You will need this kind of information if you want to produce log/error message that tell you or your user more than 'Oops, something is wrong'
Why is MyException mutable (at least in the 2nd example)
A better design than either one would be to make your custom exceptions unchecked by extending RuntimeException.
I'd want your exception to wrap the first one, so coding it this way would be better, too:
MyException exception = new MyException(e); // wrap it.
If you do that, the second one is preferred. More information is better.
IMHO, it depends as how tightly your code is coupled with SQL.
If the method is to always (*1) be coupled with SQL, I would just declare and rethrow the SQLException (after cleanup / closing resources). Upper methods that are SQL-aware would then process it as they see fit (perhaps they need all the detail, perhaps they not).
If sometime in the future you could change the method for another which does not use SQL, then I would go for the second option.
(1): Be extra pessimistic with this assumption: "I think we are not going to change" should be interpreted as "Probably we will want to change". "We are not going to change" means "We cannot change without breaking lots of other methods anyway".
One differnce would the way you will catch the exception. In the first cases you can just catch the exception and you know what the error is. In the second case you have to catch the exception and check the code to see what the error is.
I'm very new to java and the idea of try catch blocks to handle exceptions.
This roughly what I'm ending up with, and there simply has to be a better way:
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
There are more try catch blocks embedded in the same way, so that at the end, there is just a lump of catch blocks. How else should exceptions be handled, Eclipse keeps asking my to either surround with a try catch block or "Add throws declaration".
Sometimes I want to catch certain exceptions, for example if it can't find an entity, I want to print something like "Entity not found", and if the JSON string can't be parsed into an object, I want to print something like "Can't parse JSON".
(I'm used to objective-c where the are delegate methods for failure, or the method returns null and you have passed a pointer to [a pointer to] an NSError object, which will have been "filled", Is there somewhere to learn about try-catch?)
If all you're doing is catching them and printing the stack trace regardless of the exception type, you can just wrap the code in one large try/catch block. To save many "catches", you can catch java.lang.Throwable which is the interface that all exceptions implement. If not, you can have a catch for every type of checked exception the code you're calling throws, and handle them specifically.
Eclipse keeps asking you to do so because Java code will not compile if the checked exceptions are not caught, or declared to be thrown by the caller.
+Adding this comment to the answer (Thanks, Paul Tomblin):
In production quality apps you'd be logging the trace, adding some logic where you're handling the exception in a right way, taking an alternate flow, and/or re-wrapping it in another exception and throwing it, etc. It all depends on the particular problem you're trying to solve.
The idea of exception handling is that you can handle errors at points in your program flow where you can deal with them meaningfully. Rather than checking every function's return value like in C, where most of the time you can't do anything sensible other than passing the error further up, you install a try/catch block at sensible points in your program:
Basically, whenever there is a point where you can react meaningfully to an error, then catch that error, and pass everything else on. That way, error handling is only invoked when there is a plausible recovery from the error.
For example, worst case if any error stops your program from executing meaningfully, then you might almost not catch anything at all and just let the OS handle the situation (well, perhaps one single try/catch to produce a friendly error message).
Example (in C++, sorry, I'm can't type Java blind):
int main()
{
try {
while (masterloop()) { }
catch (...) {
LOG("Fatal program error, terminating!"); // nothing else we can do!
}
}
/* lots of program logic */
void process_image()
{
try {
Image im = load_image_from_disk();
/* ... */
}
catch (const OutOfMemoryExc & e) {
LOG("Not enough memory to process the image.");
return;
}
catch (const DataErrorExc & e) {
LOG("Could not read the image data.");
return;
}
catch (...) {
throw; // pass everything else along
}
}
In this example, we may try to process an image and fail for some anticipable reasons (out of memory, or failure to read the image). In that case we just return without doing work and let the program continue gracefully. All other errors are propagated up to a higher point. Most importantly, we do not need to litter the actual image processing function with error checks and responses all the time, it suffices for any code there to throw one of our two good exceptions and not worry any further.
Moral: If you have try/catch blocks absolutely everywhere, you're doing it wrong.
I know there's a lot of answers here, and they do a good job of covering how to structure the try/catch blocks. However, I'm thinking one of the things bothering you is the significant... indentation and code growth (... because I know it's not the indentation or amount of code, but the implied complexity by wrapping it and shifting it over and growing longer and longer between the opening try and enclosing catch, and I can't put a word to that apprehension).
The way to get around this is to refactor into functions the distinct bits in the code. I know it's a simplistic answer, but it's a good way to isolate individual tasks and keep the error handling fairly local to the code that requires it without padding things out vertically and horizontally with nested try/catch blocks.
You can make these methods private as they are intended for internal use only, presumably.
private Integer getDatastoreACount() {
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
return (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
// expects an Integer return, so need to deal with this
// but for simplicity I'm just simply recycling 'e'
throw e;
}
}
public void parseJSON(String jsonString) {
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
Integer dsACount = getDatastoreACount();
//etc etc
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
}
You can catch multiple exceptions in the same try e.g.
try{
xyz;
}catch(NullPointerException npx){
npx.getMessage();
}catch(ArrayOutOfBoundsException ax){
ax.getMessage();
}
Also, by declaring the Exception as throws in your method signatures you can pass the Exception up the stack.
If you're just doing something like this:
try {
do smth
try {
do smth more
...
} catch (Exception1 e1) {reaction to e1}
} catch (Exception2 e2) {reaction to e2}
You can do everything in one try-block:
try {
do smth
do smth more
...
}
catch (Exception1 e1) {reaction to e1}
catch (Exception2 e2) {reaction to e2}
You can also break this down to one catch block if you're just printing the exception:
try {
do smth
do smth more
...
}
catch (Exception e) {e.printStackTrace();}
But this doesn't if you want to do somthing more, even if e1 is thrown, like:
try {
do smth
try {
do smth more
...
} catch (Exception1 e1) {reaction to e1}
do smth even if e1 was thrown
} catch (Exception2 e2) {reaction to e2}
The last example can't be written shorter.
If you have a block of code in which more than one type of exception may be thrown, you can declare two separate catch blocks:
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
} catch (EntityNotFoundException e) {
e.printStackTrace();
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
//..etc.. as many catch blocks as needed
Alternatively, if you don't care about the exact type of the exception, you can have onyl one catch block which catches Exception (or maybe Throwable; I can't remember exactly what the superclass of exceptions is in Java).
Another point I will make now is that you might not have the most modular code. Remember, code that does one thing well makes for good, modular code. If you find that you have many nested black (whether try/catch blocks, if/else blocks, etc.) you may want to check if some of the code can be extracted into its own method. This may also make your code look better when many exceptions must be handled.
First, from a design perspective, catching and printing exceptions is not a good thing. Something went wrong, and your code just keeps going in the same way as if it went right. That is not usually correct. So: perhaps your method needs to throw these exceptions instead of catching them. Perhaps only the caller is in a position to decide what happens if something fails like this.
But otherwise, the only advice I can offer to clean up how the code looks, syntactically, is to tell you that you can write:
try {
...
} catch (...) {
...
} catch (...) {
...
}
You can also catch for a broader exception class like Exception and just write one catch block but this is bad design. In Java 7, you will be able to catch for several exception types in one block.
You should use try/catch blocks if you have a way to recover from the exception, for example if you want to check if a string is a valid integer, you can write a method (this is a lame method, but just to show the idea):
public boolean isInteger(String str) {
try {
new Integer(str);
}
catch(NumberFormatException e) {
return false;
}
return true;
}
If you don't have a way to recover from the exception and all you do is to print the stack trace, it is suggested to add throws declaration (as eclipse suggest) to the method, and let the caller handle the exception (or throw it to its caller).
If you want to handle some exceptions and throw some other, you can do it as well.
I like to box up the call behind a static method, just to keep it tidier. For example, here's my reduced Set Json Value call.
private static boolean setJsonValue(JSONObject j,String key,Object value)
{
try
{
if(value instanceof Integer)
{
// numbers are special. We want them unquoted.
int valueI = (Integer)value;
j.put(key,valueI);
}
else
j.put(key,value);
return true;
}
catch (JSONException e)
{
// do nothing, it turns out
return false;
}
}
...and then I ignore the return values, because I am bad.
Somewhere or other I have a similar Get method, that returns null if it fails. You get the idea.
You have two basic code-style choices here (that don't involve changing method signatures)
Method1: Put everything in the one try catch and have multiple catch blocks, like this:
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
e.printStackTrace();
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
Method 2: Break up your code into sections that each have one catch, like this:
String qURL = null;
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
Method 2 is the recommended one, as it makes it obvious which lines are throwing which exceptions and generally segments the code into natural processing blocks.
Create another exception and put it below or above of the other exception. Depends on the context of your application.