Reputation: 3101
I know that it's a bad practice to use Exceptions for flow control. But I faced the following situation: I need to parse JSON file, and if there are corrupted values for the key of a record I want to just log it and continue to parse another object from jsonArray
. And even if the value is null I want to ignore it and go on.
So in my current implementation I use a try/catch block with continue. What would be a more correct approach here?
Here is how I've implemented it:
public static void parseMetrics(JSONParser parser, File jsonFile,
String metricKey, List<String> metricsList) throws IOException, ParseException {
JSONArray jsonArray = (JSONArray) parser.parse(new InputStreamReader(new FileInputStream(jsonFile)));
for (Object obj : jsonArray) {
try {
JSONObject jsonObject = (JSONObject) obj;
String metricValue = (String) jsonObject.get(metricKey);
Long metricDate = parseDate(jsonObject);
metricsList.add(new Metric(metricValue, metricDate));
} catch (java.text.ParseException e) {
continue;
log.error("Error when parsing JSON", e);
}
}
}
Upvotes: 0
Views: 1530
Reputation: 131396
Actually you want to log with the error
level the parsing problem.
So throwing a exception makes sense.
If the parsing error is an abnormal situation you should keep your way but just without the continue
that is not convenient here :
for (Object obj : jsonArray) {
try {
JSONObject jsonObject = (JSONObject) obj;
String metricValue = (String) jsonObject.get(metricKey);
Long metricDate = parseDate(jsonObject);
metricsList.add(new Metric(metricValue, metricDate));
} catch (java.text.ParseException e) {
log.error("Error when parsing JSON", e);
}
}
But if you consider that the parsing problem is not an issue to log but a normal scenario that may happen, indeed you don't have to propagate the exception from parseDate()
but you could return something like OptionalLong
instead of Long
.
It would give from the client side :
for (Object obj : jsonArray) {
JSONObject jsonObject = (JSONObject) obj;
String metricValue = (String) jsonObject.get(metricKey);
OptionalLong metricDate = parseDate(jsonObject);
metricDate.ifPresent(d -> metricsList.add(new Metric(metricValue, d));
}
You could also add a log in debug
or info level
if it makes sense.
Upvotes: 1