samba
samba

Reputation: 3101

Java - a better way to ignore invalid records when parsing JSON

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

Answers (1)

davidxxx
davidxxx

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

Related Questions