I am writing a webservice, where in the webservice read a bunch of records one by one, process them and store them into the database.
If for a record, a field is missing, then an error object is created with the missing information and sent back as response.
Inspite of all null checks that I have done, there might be some null pointer exceptions hanging around as I have no control over the records coming in to the service.
If say for 45th record, a NPE occurs, the service breaks. Instead of this, I want the service to proceed and process the next record.
So, is it ok if I catch the NPE in such cases or any there any better alternatives.I have read that catching NPE isn't recommended but not sure if I have to break the rule here.
If you cannot stop the NullPointerException with null checks, then the only alternative is to catch it. However, I cannot think of an instance where null checks cannot prevent a NullPointerException.
If a null pointer is expected, I see no problem catching the NullPointerException. I think it's cleaner than having 50 billion if not nulls...
Although, you should not catch NPEs in general, it is acceptable catching them if you know what you do. You should avoid catching NPEs and not rethrowing them in complex chains like
try {
a.getB().getC().getD();
} catch (NullPointerException e) {
// only the stack trace indicates where the exception occured
}
Let's say in the above example you expect the NPE to be thrown on getD(), try to refactor your code to
C c = a.getB().getC();
try {
c.getD();
} catch (NullPointerException e) {
// you know that either `c` is null or that the exception was thrown in `getD()`
}
My 2 cents... neverthesless, if you know that NPEs can occur inside the WS request you should guard it accordingly:
if (c != null) {
// do something (getD() can still throw a NPW)
c.getD();
} else {
}
If there are NPEs resulting from invalid records, and you have no control over the records, then your logic should attempt to validate the records before processing them. The best way to do this would be to loop over each record, checking for the valid format, keeping track of invalid rows. After validation, if any invalid rows exist, you can report them in a meaningful format back to the UI. Otherwise proceed with the actual processing.
List<String> invalidRows = new ArrayList<String>();
for each row {
if (row is missing x) {
invalidRows.add("Record " + rowNumber + " is missing X");
}
if (row is missing y) {
invalidRows.add("Record " + rowNumber + " is missing Y");
}
}
if (invalidRows.isEmpty()) {
//process
}
else {
format and return error message using data collected
}
(note that the use of a List<String> is a general example - you should store and then format this information in the way that makes the most sense for your situation.)
An alternative to this approach would be to do your validation and processing in the same loop, keeping track of invalid rows and processing valid ones. At the end, the UI could report how many succeeded and which failed.
Additionally, one might wrap web services in a last defense to make unhandled exceptions more manageable and consumable by the client UI, or at least easier for you to read:
#WebMethod(operationName = "myMethod")
public String myMethod() {
try {
//logic
return "done";
}
catch (Throwable error) {
//returns formatted String representing error - UI should check for this
return MyExceptionFormatter.formatUnhandled(error);
}
}
Your custom formatting would assemble a more meaningful String representing the exception, potentially in XML format. This all depends on what your client UI is expecting.
Related
I am not able to understand why Java doesn't allow to change exception message of an exception of type Exception (or its superclass Throwable) once it has been created. It allows to change the stackTrace using setStackTrace but not the message.
The use case I have seems genuine to me and would appreciate some alternative.
Use case
I have a controller service X that calls let's say 10 other dependent services. To make debugging easy, if a dependent service throws some exception we want to surface some identifiers from service X to its upstream to identify the failed request easily. For this we have requestId which we create and set for each dependency.
Now to avoid duplication across all dependent services and simplify code, we can create a common interceptor that allows us to do some work before and after each call. Something like -
// do some work
requestId = getRequestId(); // create or somehow get requestId
dependentService.setRequestId(requestId);
try {
dependentService.call();
}
catch (Exception e) {
e.setMessage(e.getMessage() + ... + requestId);
throw e;
}
//do some work
But Java doesn't allow us to set message. At the same time, we want to preserve the exception and its type (which could be any of the custom types defined by dependent services), so I don't want to do something like throw new Exception(e.getMessage() + ...)
It's not really what it's meant for, but you could attach another exception with addSuppressed:
} catch (Exception e) {
e.addSuppressed(new ExtraInfoException(...));
throw e;
}
where ... contains the extra info you want to include.
The advantage of this over adding to the exception message is that you can define your ExtraInfoException so that it has the info you want in fields, rather than having to parse it back out of the exception message.
With that said, a more idiomatic way to attach more exception info it would be:
} catch (Exception e) {
throw new ExtraInfoException(e, ...);
}
which has exactly the same advantage of allowing you to return structured information, with the additional advantage that you can catch ExtraInfoException directly, rather than catching Exception and then hunting for the extra info reflectively.
Why doesn't Java have setMessage in Exception/Throwable classes?
The answer to your question is that they (the library designers) did not think that changing a message on an exception was a useful thing to do.
To a large degree1, the designers have taken the view that they shouldn't design the APIs to directly support all possible use-cases ... including the obscure ones that almost nobody will encounter. Like your one2.
And in your case, there are other ways to achieve what you are trying to do; see the other answers.
I did a quick search of the Java bugs database to see if someone else had put in an RFE to request a setMessage method for Throwable or Exception. I couldn't find anything. If your requirement was even slightly common, there would probably be an RFE with an explanation of why it was declined.
1 - Obviously, there are exceptions to this, but that is beside the point.
2 - Obviously you would disagree that your use-case is obscure, but that that is also beside the point. The question is why they haven't implemented this, not whether they were wrong. (Asking / debating whether they were wrong is off-topic, because it is a matter of opinion.)
Resetting a message it's some kind of rewriting the history. You have a catch block when you catch exception and handle them. If you need to throw an exception during the handling, it's a different problem and an exception should be different.
} catch (SomeException e) {
// here we have SomeException and we want to handle it.
// if we can't we throw a new one, because we have a problem with handling.
// if the handling problem cause is SomeException we put it at the cause.
throw new AnotherException("with some message", e);
}
And in the stacks trace we will see that we have AnotherException because of SomeException which gives us information about the root of problem.
Just simply throw new instance like this:
try {
...
} catch(Exception ex) {
throw new Exception ("new message", ex);
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
In this answer, the code provided is:
void greet(String name) {
if (name == null) {
throw new IllegalArgumentException("Cannot greet null");
}
System.out.println("Hello, " + name);
}
I have seen similar examples on all sites where I went to learn the 'throw' keyword. What doesn't make sense to me whenever I see such examples is why would one simply not print: "Cannot greet null" instead of throwing an exception.
Questions:
Are there better examples of the utility of the throw keyword? (I am just going to pass out of high school and know only high school level Java programming so please avoid complicated examples)
In the given example, why did the user choose to throw an exception instead of simply printing the error?
Now it is time to revise the concept of Exception Handling in the Java.
First of All what is exception, whenever there is some error or say problem occur while executing the lines of code it is called the Exception.
For Example,
If a person divides something with 0, then it will give an exception as computer cannot handle the undefined entity.
Another example will be while you have declared a Scanner in order to get in integer input, but user enters an alphabet so it will also cause the exception.
Here we do exception handling, which means that we will handle exception in such a way that it will not cause program to close, those specific line which have been enclosed in the try and catch statement will not work properly but other lines will executed.
Now if we have made a method that do something lets suppose prints a line, and there is an exception occurred while printing that line, here we can do two things handle that exception at place where it has occurred or throw it.
If we handle exception at that place it is okay, and if we throw it then we have to catch it place where we have called that method.
Now as there are two types of Exceptions
1) Run Time Exception Which We Call Unchecked Exception
2) Compile Time Exception Which We Call Checked Exception
Both exceptions can be handle at the class level and method level too, one more thing we can do chain exceptional handling too. Which means that one class will throw exception to other and so on.
I think following answer can help you to understand ....
Are there better examples of the utility of the throw keyword?
Basically Throw and Throws are used to prevent the application for getting error or crashing by throwing exception.
Throws are used in the method signature and Throw are used to prevent the flow from getting error.
So here is a simple example for it.
public class Test {
// here we have used "throws" in method signature
// because we are throwing new Exception(), if array is null
public static int getValue(int[] array, int index) throws Exception {
// here we are preventing application from getting
// unconditional error (NullPointer exception)
// if array is null, then we are throwing new Exception()
if(array == null) {
throw new Exception();
}
int value = array[index];
return value;
}
public static void main(String[] args) {
int[] array = null;
// here we are wrapping our getValue() function call to try catch block
// because getValue() function can throws Exception
// so we are making it safe to execute our program
try {
int value = getValue(array, 0);
System.out.println("value " + value);
} catch (Exception e) {
System.out.println("Provided array is null... so we caught the exception...");
}
}
}
if you want to know more about how throw and throws works... then you need to know about Exception Handling (Checked and Unchecked) also.
In the given example, why did the user choose to throw an exception instead of simply printing the error?
As per the given example, your function purpose is to greet, but if some other function call greet() with
null value then there is no any reason to greet like Hello, null, so he throw an exception before executing the statement. like...
void greet(String name) {
System.out.println("Hello, " + name);
}
String myName = null;
greet(myName); // it will print "Hello, null";
'Throw' keyword is used to notify the caller that the argument passed is not valid (in this case), or in general, something went wrong while executing the code called by the caller.
Consider an example where you are writing an online shopping application. Following would be the simple sequence of events:
User scrolls through items and selects one or more items
Items are added into the cart and user clicks check out
User is redirected to 3rd party's payment page where he types in card details and makes the payment
User is shown the success page
Now, during payment, if the card number is incorrect or user doesn't have enough balance in the card, would you throw the error back to the caller (i.e. shopping app) or just log it on the console (on payment provider's side) and return the response? Of course the former, so this is just to let the caller know that there is an error and he should handle it gracefully (by showing appropriate message on checkout in our case).
A throw statement abruptly terminates the execution of the current function, and returns control right back to the caller, forcing them to deal with the error, or rethrow the exception up the chain.
An exception object contains lots of information about where and why an error occurred beyond just the error message. It keeps track of where in the call stack the error happened, and allows you to look up the sequence of calls that led up to it.
A print statement simply could not do all these things. Your example is already a good one. The job of the greet function is to print a greeting. If you pass in null, the function is unable to do so. Printing a message here would be potentially confusing. Instead, it forces you to deal with the fact that you have it invalid input rather than printing a benign message that someone might mistake for a greeting.
Try Java 8 Optional:
String nullVal = null;
System.out.println(Optional.ofNullable(nullVal).orElseGet(() -> null));
String notNull = "Hello Optional";
System.out.println(Optional.ofNullable(notNull).orElseGet(() -> null));
The method can be modify like this:
public static void greet(String name) {
System.out.println("Hello, " + Optional.ofNullable(name).orElseGet(()->null));
}
Assume a function checks that in the passed directory is no malicious file. That could be a void method where you need to catch the exception for the rare case, bypassing the normal processing after the call.
try {
checkDirectorySafe("/home/Donald");
...
} catch (VirusException e) {
...
}
The catch might be late in the code and also catch exceptions in other parts.
There is an other advantage. The function can check all files in the directory and for all subdirectories need only recursively call itself with the subdirectory path. On an exception the call stack is unwound upto the catch.
The Alternative would be to have a boolean or Optional result, and add if code. If the function also needs to return some data, that could become slightly uglier.
An exception is like a toilet in a mall.
I am looking to create a exception factory
I have a service that connects to different data stores and these data stores throw a number of exceptions.
I do not want to return these exceptions to users of the service but instead return higher level exception
e.g. storeServiceTransientReadException
When connecting to the data store I will use a try, catch throw pattern; e.g for a Cassandra connection:
public ResultSet safeExecute(Statement statement) throws StoreServiceException {
try {
return session.execute(statement);
}
catch(QueryExecutionException ex){
log.error(ex);
StoreServiceException storeException = StoreServiceExceptionFactory.getTransientException(ex);
throw storeException;
}
In the cassandra example I want the factory to create a read or write storeServiceException exception depending on whether the exception is a ReadFailureException, ReadTimeoutException, WriteFailureException or WriteTimeoutException
For other data stores I want to follow the same pattern then users of the service will only have to worry about the service errors and not specific data store errors.
For the factory I was think something along the lines of (in pseudo):
public class ExceptionsFactory {
public StoreServiceTransientException getTransientException(Exception ex){
if ReadException
return StoreServiceTransientException("read exception ")
if WriteException
return StoreServiceTransientException("write exception ")
}
public StoreServiceNonTransientException getTransientNonException(Exception ex){
if ReadException
return StoreServiceNonTransientException("read exception ")
if WriteException
return StoreServiceNonTransientException("write exception ")
}
But I cannot find many online example of this which worries me.
It is a really bad idea?
I should just have lots more specific catch blocks that return the storeServiceException I want?
It is a really bad idea? In my opinion, yes. This is a bad idea. The expensive part of using Exception(s) is filling in the stack trace. If you pre-create and save the Exception you throw then the stack trace will be meaningless (or at least of greatly reduced value). You aren't currently logging stack traces, so I would also change
log.error(ex);
to
log.error("Caught exception: " + ex.getMessage(), ex);
And similarly instantiate exceptions with the underlying cause -
throw new storeServiceException("Exception in storage.", ex);
And the name should follow normal naming conventions. Java class names start with a capital letter - yours' looks like a variable.
For my Java application, I am creating an instance of a user information object and populating it with a service that I don't control the source for.
The code looks like this:
// username given as parameter
UserInfo ui = new UserInfo();
try {
DirectoryUser du = LDAPService.findUser(username);
if (du!=null) {
ui.setUserInfo(du.getUserInfo());
}
} catch (Exception e) {
// Whatever
}
If LDAPService.findUser() can't locate a user, it will throw a NullPointerException and grind the rest of my application to a stop. It's okay if the user information isn't populated, so I want to be able to continue without causing everything else to start throwing exceptions.
Is there a way to do this?
I've upvoted Amir Afghani's answer, which seems to be the only one as of yet that actually answers the question.
But I would have written it like this instead:
UserInfo ui = new UserInfo();
DirectoryUser du = null;
try {
du = LDAPService.findUser(username);
} catch (NullPointerException npe) {
// It's fine if findUser throws a NPE
}
if (du != null) {
ui.setUserInfo(du.getUserInfo());
}
Of course, it depends on whether or not you want to catch NPEs from the ui.setUserInfo() and du.getUserInfo() calls.
You could catch the NullPointerException explicitly and ignore it - though its generally not recommended. You should not, however, ignore all exceptions as you're currently doing.
UserInfo ui = new UserInfo();
try {
DirectoryUser du = LDAPService.findUser(username);
if (du!=null) {
ui.setUserInfo(du.getUserInfo());
}
} catch (NullPointerException npe) {
// Lulz # your NPE
Logger.log("No user info for " +username+ ", will find some way to cope");
}
You are already doing it in your code. Run this example below. The catch will "handle" the exception, and you can move forward, assuming whatever you caught and handled did not break code down the road which you did not anticipate.
try{
throw new Exception();
}catch (Exception ex){
ex.printStackTrace();
}
System.out.println("Made it!");
However, you should always handle an exception properly. You can get yourself into some pretty messy situations and write difficult to maintain code by "ignoring" exceptions. You should only do this if you are actually handling whatever went wrong with the exception to the point that it really does not affect the rest of the program.
It's generally considered a bad idea to ignore exceptions. Usually, if it's appropriate, you want to either notify the user of the issue (if they would care) or at the very least, log the exception, or print the stack trace to the console.
However, if that's truly not necessary (you're the one making the decision) then no, there's no other way to ignore an exception that forces you to catch it. The only revision, in that case, that I would suggest is explicitly listing the the class of the Exceptions you're ignoring, and some comment as to why you're ignoring them, rather than simply ignoring any exception, as you've done in your example.
You are actually ignoring exception in your code. But I suggest you to reconsider.
Here is a quote from Coding Crimes: Ignoring Exceptions
For a start, the exception should be logged at the very least, not
just written out to the console. Also, in most cases, the exception
should be thrown back to the caller for them to deal with. If it
doesn't need to be thrown back to the caller, then the exception
should be handled. And some comments would be nice too.
The usual excuse for this type of code is "I didn't have time", but
there is a ripple effect when code is left in this state. Chances are
that most of this type of code will never get out in the final
production. Code reviews or static analysis tools should catch this
error pattern. But that's no excuse, all this does is add time to the
maintainance and debugging of the software.
Even if you are ignoring it I suggest you to use specific exception names instead of superclass name. ie., Use NullPointerException instead of Exception in your catch clause.
You can write a try - catch block around the line you want to have ignored.
Like in the example code of yours. If you just continue your code below the closing bracket of the catch block everythings fine.
LDAPService should contain method like LDAPService.isExists(String userName) use it to prevent NPE to be thrown. If is not - this could be a workaround, but use Logging to post some warning..
Printing the STACK trace, logging it or send message to the user, are very bad ways to process the exceptions. Does any one can describe solutions to fix the exception in proper steps then can trying the broken instruction again?
In the following scenario, I was trying to see how to handle this code and it how it relates to Runtimexception. I have read that is generally better to throw runtime exceptions as opposed to rely on static exceptions. And maybe even better to catch a static checked exception and throw an unchecked exception.
Are there any scenarios where it is OK to catch a static exception, possibly the catch-all Exception and just handle the exception. Possibly log an error message and continue on.
In the code below, in the execute1 method and execute2 method, let us say there is volatile code, do you catch the static exception and then rethrow? Or possibly if there are other errors:
if (null == someObj) { throw new RuntimeException(); }
Is this an approach you use?
Pseudo Code:
public class SomeWorkerObject {
private String field1 = "";
private String field2 = "";
public setField1() { }
public setField2() { }
// Do I throw runtime exception here?
public execute1() {
try {
// Do something with field 1
// Do something with field 2
} catch(SomeException) {
throw new RuntimeException();
}
}
// Do I throw runtime exception here?
public execute2() {
try {
// Do something with field 1
// Do something with field 2
} catch(SomeException) {
throw new RuntimeException();
}
}
}
public class TheWeb {
public void processWebRequest() {
SomeWorkerObject obj = new SomeWorkerObject();
obj.setField1("something");
obj.setField2("something");
obj.execute1();
obj.execute2();
// Possibility that runtime exception thrown?
doSomethingWith(obj);
}
}
I have a couple of problems with this code. There are times when I don't want a runtimeexception to be thrown because then execution stops in the calling method. It seems if I trap the errors in the method, maybe I can continue. But I will know if I can continue later on the program.
In the example above, what if obj.execute1() throws a Runtimeexception, then the code exits?
Edited: This guy seems to answer a lot of my questions, but I still want to hear your opinions.
http://misko.hevery.com/2009/09/16/checked-exceptions-i-love-you-but-you-have-to-go/
"Checked exceptions force me to write catch blocks which are meaningless: more code, harder to read, and higher chance that I will mess up the rethrow logic and eat the exception."
When catching an exception and throwing RuntimeException instead, it is important to set the original exception as a cause for the RuntimeException. i.e.
throw new RuntimeException(originalException).
Otherwise you will not know what was the problem in the first place.
Rethrowing checked exceptions as unchecked exceptions should only be done if you are sure that the checked exception is not to be expected.
Here's a typical example:
try {
hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException e) {
// Unexpected exception. "MD5" is just hardcoded and supported.
throw new RuntimeException("MD5 should be supported?", e);
} catch (UnsupportedEncodingException e) {
// Unexpected exception. "UTF-8" is just hardcoded and supported.
throw new RuntimeException("UTF-8 should be supported?", e);
}
There are times when I don't want a
runtimeexception to be thrown because
then execution stops in the calling
method. It seems if I trap the errors
in the method, maybe I can continue.
But I will know if I can continue
later on the program.
You have the right idea. The advice about throwing RuntimeException is that it doesn't require the caller to use a try-block or a 'throws' clause.
If your code can recover from an exception than it really should catch it and not throw anything.
One of the first rules about exceptions is to not abuse them to pass state in your application. They should be used for exceptional situations, not as alternative return values.
The second rule is to catch exceptions at the level you process them. Catch and rethrow does not add much. Any cleanup code in your method should be done in a finally block.
In my opinion catching checked exceptions and rethrowing them as runtime exceptions is abusing the system. It feels like working around the "limitations" of design by contract instead of using those "limitations" to get a more robust application.
Whether or not to handle an exception or simply rethrow it depends on your use case.
For example, if you're reading a file to load data into your application, and some IO error occurs, you're unlikely to recover from the error, so rethrowing the error to the top and consequently terminating the application isn't a bad course of action.
Conversely, if you're anticipating recoverable errors then you should absolutely catch and handle the errors. For example, you may have users entering data in a form. If they enter data incorrectly, your input processing code may throw an exception (e.g. NumberFormatException when parsing a malformed number string). Your code should catch these exceptions and return an error the user, prompting for correct input.
On an additional note, it's probably bad form to wrap all your exceptions with RuntimeException. If your code is going to be reused somewhere else, it is very helpful to have checked exceptions to signify that your code can fail in certain ways.
For example, assume your code is to parse configuration data from a file. Obviously, an IO error may occur, so you will have to catch an IOException somewhere in your code. You probably won't be able to do anything about the error, so you will have to rethrow it. However, someone calling into your code may well be able to handle such an error, for example by backing off to configuration defaults if the configuration can't be loaded from the file. By marking your API with checked exceptions, someone using your code can clearly see where an error may occur, and can thus write the error handling code at the appropriate place. If instead you simply throw a RuntimeException, the developer using your code won't be aware of possible errors until they creep up during testing.