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_jsonreturns 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
evalis simplest and core.
Common Pitfalls to Avoid
- Malformed JSON literal strings with missing or extra characters cause parse failures.
- Not wrapping
decode_jsoninevalmeans your script dies on bad JSON. - Not checking
$@afterevalmeans 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_jsonto parse strings into Perl structures. - An
evalblock 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
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.
(empty)Was this helpful?
Related Questions
- How to validate JSON schema in Perl?
- How to use JSON::MaybeXS for automatic backend selection in Perl?
- How to convert Perl hash to YAML string?
- How to load YAML configuration file in Perl script?
- How to escape special characters when encoding JSON in Perl?
- How to use Cpanel::JSON::XS for JSON processing in Perl?