serialization intermediate

How to handle JSON parsing errors in Perl?

Question

How to handle JSON parsing errors in Perl?

Handling JSON parsing errors in Perl is crucial for writing robust programs that consume JSON data. The core JSON module (which comes with Perl 5.14+ via JSON::PP) provides simple functions like decode_json to turn JSON strings into Perl data structures. When parsing invalid JSON, decode_json throws an exception (dies), so you must trap that to avoid crashing your script.

How to Handle JSON Parsing Errors

You can catch exceptions using an eval block, which executes its code and traps any runtime errors in $@. If $@ is nonempty after eval, a parse error occurred and you can handle it gracefully (print an error, fallback, etc.). This method avoids needing external modules like Try::Tiny, which you cannot use given the constraints.

Perl-Specific Concepts

  • Sigils: $ for scalars (strings, error messages), @ and % for arrays and hashes; JSON decoding returns references, often hashrefs ($data->{key}).
  • Context: decode_json returns a scalar containing a reference to a data structure.
  • TMTOWTDI (There's More Than One Way To Do It): You can parse JSON and handle errors in several ways, but eval is simplest and core.

Common Pitfalls to Avoid

  • Malformed JSON literal strings with missing or extra characters cause parse failures.
  • Not wrapping decode_json in eval means your script dies on bad JSON.
  • Not checking $@ after eval means errors go unnoticed.
  • Forgetting to use JSON;.

Runnable Example

The example below attempts to decode two JSON strings—one valid, one invalid—with proper error handling. It demonstrates successful parsing and catches errors gracefully.

use strict;
use warnings;
use JSON;

my $valid_json = q({"name":"Alice","age":30,"languages":["Perl","Python","JavaScript"]});
my $invalid_json = q({"name": "Bob", "age": "twenty";});  # Note: extra semicolon causes JSON to be malformed

foreach my $json_str ($valid_json, $invalid_json) {
    print "Parsing JSON: $json_str\n";

    my $data;
    eval {
        $data = decode_json($json_str);
    };

    if ($@) {
        print "Error parsing JSON: $@\n";
    } else {
        # Access parsed data (hash reference)
        print "Name: $data->{name}, Age: $data->{age}\n";
        print "Languages: " . join(", ", @{$data->{languages} // []}) . "\n";
    }

    print "\n";
}

Explanation

  • The code uses decode_json to parse strings into Perl structures.
  • An eval block catches exceptions from malformed JSON.
  • If parsing fails, $@ holds the error, printed for debugging.
  • If successful, you access data via hashrefs ($data->{key}) and arrayrefs.
  • The invalid JSON has an extra semicolon, ensuring a parse failure triggers error handling.

This approach ensures your Perl JSON handling can detect and recover from malformed input, improving the robustness of your scripts.

Verified Code

Executed in a sandbox to capture real output. • v5.34.1 • 20ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Parsing JSON: {"name":"Alice","age":30,"languages":["Perl","Python","JavaScript"]}
Name: Alice, Age: 30
Languages: Perl, Python, JavaScript

Parsing JSON: {"name": "Bob", "age": "twenty";}
Error parsing JSON: , or } expected while parsing object/hash, at character offset 31 (before ";}") at - line 13.


STDERR
(empty)

Was this helpful?

Related Questions