• Post Reply Bookmark Topic Watch Topic
  • New Topic

Best practice for this error handling scenario?  RSS feed

 
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have an android application that consumes a REST API and parses a JSON response. Sometimes the json response is unexpected. For example, if an attribute is missing one day, this could lead to a NPE if not handled properly. To resolve this, I check to see if the parsed value is null to avoid the app crashing from an NPE. That's a lot of if statements in my try block, one for each parsed variable Is there a better way to go about this?
 
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
peter pham wrote:I have an android application that consumes a REST API and parses a JSON response. Sometimes the json response is unexpected. For example, if an attribute is missing one day, this could lead to a NPE if not handled properly. To resolve this, I check to see if the parsed value is null to avoid the app crashing from an NPE. That's a lot of if statements in my try block, one for each parsed variable Is there a better way to go about this?

Probably, but first we'd need to know:
1. What version of Java is this Android app using?
2. (probably more important) What do you plan to do if you do get a null value?

And it's that last one that's likely to be the toughest to answer, because there may be more than one depending on which value (or values) is/are null.

If you could also tell us a bit more about why a response might be "unexpected", or why an attribute might be "missing", it might help us to advise. Indeed, if you could tell what this app is doing, you might get responses from people who've been through the same problem.

Winston
 
peter pham
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
peter pham wrote:I have an android application that consumes a REST API and parses a JSON response. Sometimes the json response is unexpected. For example, if an attribute is missing one day, this could lead to a NPE if not handled properly. To resolve this, I check to see if the parsed value is null to avoid the app crashing from an NPE. That's a lot of if statements in my try block, one for each parsed variable Is there a better way to go about this?

Probably, but first we'd need to know:
1. What version of Java is this Android app using?
2. (probably more important) What do you plan to do if you do get a null value?

And it's that last one that's likely to be the toughest to answer, because there may be more than one depending on which value (or values) is/are null.

If you could also tell us a bit more about why a response might be "unexpected", or why an attribute might be "missing", it might help us to advise. Indeed, if you could tell what this app is doing, you might get responses from people who've been through the same problem.

Winston


1. Java 1.7
2. I have a List of "Store" objects parsed from json. Most of the store objects have an attribute in the json called "years", but one doesnt. When this store's json is parsed, a JSONParseException is caught in the generic Exception e catch block. This store never made it to the line of code to create a store object before the exception was thrown, and null is returned. I want to display the years, so later on I concatenate this int with a string, NPE occurs, and the app crashes.
 
Sheriff
Posts: 22844
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you're getting a JSONParseException, that sounds to me like more than just a missing attribute. I would suggest you look at the JSON which doesn't parse and see what the problem is with it.
 
peter pham
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:If you're getting a JSONParseException, that sounds to me like more than just a missing attribute. I would suggest you look at the JSON which doesn't parse and see what the problem is with it.


It says org.json.JSONException: no value for distance



Somewhere in that function a json attribute might be missing. It isn't missing the other times it was called for other "currentStoreJSON" values, but in this case it is.

What is the best way to structure the code so that if an attribute like "distance" is missing, the store is instantiated with the other values from the json, and the "distance" attribute is any placeholder value?

Currently the exception will be caught so values present in the json such as "address" will not be used, and this function returns null.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
peter pham wrote:Currently the exception will be caught so values present in the json such as "address" will not be used, and this function returns null.

And I'm afraid that's not a very good way to go. It's almost always a bad idea to:
(a) Use Exceptions to drive logic (although you may not have any option in this case).
(b) Consume an Exception without, at the very least, logging it. You're doing nothing.
(c) Catch Exception (or Error; or any other generic Throwable). It would appear that you're interested specifically in JSONParseException, so catch THAT.

Somewhere in that function a json attribute might be missing. It isn't missing the other times it was called for other "currentStoreJSON" values, but in this case it is.

Then I'd say that you need to work out why you're not getting it this time. It could be that an attribute simply isn't applicable to a particular Store; but if that's the case, wouldn't that make it a specific type of Store?

My worry is that your current "solution" is simply a band-aid to work around a situation that you don't fully understand.

For example: What if more than one attribute is missing? What do you do then? What if ALL of them are missing? Do you want some sort of "default" Store object? - ie: at what point does a "missing attribute" become a genuine error?

There's an old programming adage that's worth remembering: Solve the problem; don't treat the symptoms.

What is the best way to structure the code so that if an attribute like "distance" is missing, the store is instantiated with the other values from the json, and the "distance" attribute is any placeholder value?

Well, one way of supplying "defaults" for class fields (especially if you have lots of them) is to use a Builder.

But I strongly advise you to find out WHY you're not getting those values before you start going down that route.

Winston
 
Paul Clapham
Sheriff
Posts: 22844
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
peter pham wrote:Somewhere in that function a json attribute might be missing.


You need to step back from implementing the idea you had, and go back to the step where you figure out what the problem is. Don't start solving problems before you know what they are. To do that you look at the stack trace, which tells you what line of code threw the exception. What line of code is that?
 
peter pham
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I understand completely what's happening. I am consuming a publicly available API. I am getting stores in a zip code. 18/20 of the stores have all the json attributes, the other 2 don't. Why? I don't know and I'm not supposed to know, a stranger provided this data. The problem is as simple as the one json attribute, say "distance", is not available for store #10, so an exception is thrown and the parsing of the other json attributes is not accomplished.

The solution seems difficult since it poses the question: "what if X attribute is missing but Y and Z aren't", or "what if X and Y are missing but Z isn't"? The point is I want to code as if I were looking at the json and able to create store objects manually, placing placeholder or default values for attributes that weren't given by whoever wrote the API. It doesn't matter why the data isn't available, or if it should be a "specific type of store", I don't have control of that. When writing a software application you don't have control over ALL the moving parts.
 
Paul Clapham
Sheriff
Posts: 22844
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
peter pham wrote:I understand completely what's happening. I am consuming a publicly available API. I am getting stores in a zip code. 18/20 of the stores have all the json attributes, the other 2 don't. Why? I don't know and I'm not supposed to know, a stranger provided this data. The problem is as simple as the one json attribute, say "distance", is not available for store #10, so an exception is thrown and the parsing of the other json attributes is not accomplished.


So catch the exception and do whatever your business requirements say should be done if the distance is missing.

That's assuming you can catch the exception and identify specifically what attribute was missing. I have no idea whether you can do that or not because you have avoided posting any detailed information which tells us that. My guess is that it's the line of code Double sDist = sLoc.getDouble("distance"); which is throwing the exception, in which case you could certainly catch the exception there, but even when I asked you about the stack trace you didn't respond to that.
 
peter pham
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul Clapham wrote:
peter pham wrote:I understand completely what's happening. I am consuming a publicly available API. I am getting stores in a zip code. 18/20 of the stores have all the json attributes, the other 2 don't. Why? I don't know and I'm not supposed to know, a stranger provided this data. The problem is as simple as the one json attribute, say "distance", is not available for store #10, so an exception is thrown and the parsing of the other json attributes is not accomplished.


So catch the exception and do whatever your business requirements say should be done if the distance is missing.

That's assuming you can catch the exception and identify specifically what attribute was missing. I have no idea whether you can do that or not because you have avoided posting any detailed information which tells us that. My guess is that it's the line of code Double sDist = sLoc.getDouble("distance"); which is throwing the exception, in which case you could certainly catch the exception there, but even when I asked you about the stack trace you didn't respond to that.


"It says org.json.JSONException: no value for distance". That is the root of the problem that I've determined by reading the stacktrace. I could show you the whole thing in its thread handler and zygote glory, but that's not useful. I then posted the code, which I consider "detailed information".

I can catch it if the distance is missing, but what if the street is missing and the distance is not? What can I do to avoid different nested catch blocks?
 
Paul Clapham
Sheriff
Posts: 22844
43
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why would the catch blocks be nested?

(Let me also mention that the question I just asked could be answered easily if you posted the information about which line of code is throwing the exception, which I have asked twice already. I may soon have to assume that you're not interested in getting good answers to your questions.)
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
peter pham wrote:"It says org.json.JSONException: no value for distance".

So, what do you propose to do about it? From the sound of it, you want to plug in some "default" value - and I've already provided one suggestion for how to do that.

However, unless you know why it's happening (and I'm afraid the "3rd party software" excuse doesn't hold water. Nobody in their right mind would use software that simply "misses things out" arbitrarily without explaining why or when; so maybe you just need to read the documentation) your "solution" is almost certain to be less than optimal ... and very possibly WRONG.

Winston
 
Sheriff
Posts: 11494
180
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The JSONObject class has other methods that don't throw an exception and will give back a default value which you can provide. There is also a method that you can use to check if a value exists. See the optXxxxx() methods and the has() method. If you can avoid using a try-catch block, you should. Otherwise, if you really want to use the getXxxxx() methods, I think Winston's suggestion to use a Builder is the best way to go.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!