0

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.

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

hmm..There are null checks for almost all the fields. But i just need a last form of defense. I mean, i do not want the webservice to come to a halt just for one record. I am more specific about the NPE as I have no control on the input coming-in and its a large record.So, inspite of all the null checks...a Null value might have crept in..
There's no harm in catching it.
1

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...

3 Comments

+1 more.. it's fair enough to catch the NPE for every iteration and proceed to the next one if that's what is the business need. There are scenarios where even if one of the records has an issue fail the complete batch and in those scenarios you wouldn't want to catch NPE for each of them.
my issue is not one of those...if there is a failure with one record, i just have to go to the next record
@Ben sounds like a for(){try{}catch(){}} is exactly what you need then.
0

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 {
}

5 Comments

hmmm...I did all null checks everywhere where there is potantial for a NPE. But i am looking out for a last line of defense as I do not want my service to come to a halt because of an NPE.
Is there any where i can catch the NPE, extract the information from it and attach it to my error object and them proceed to the next record.
Your last resort could be to surround your logic using a generic throws (Exception e) clause provide the exception details to the caller. In general, I'd not do so. In fact, the caller signs a contract to support your service specification. If the caller is not able to fulfill this contract it's his fault. BTW: providing internal exception details to the outside word is a security issue... instead submit a generic error code.
///Is there any where i can catch the NPE, extract the information from it and attach it to my error object and them proceed to the next record.////
ya,,,this is what i meant...i send out error codes only, but not the complete stack trace or the exception...
0

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.

2 Comments

hmmm...I did all null checks everywhere where there is potantial for a NPE. But i am looking out for a last line of defense as I do not want my service to come to a halt because of an NPE
Is there any where i can catch the NPE, extract the information from it and attach it to my error object and them proceed to the next record.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.