Skip to content

--profile reports a missing or unreadable file with a raw Perl error and exit 1, instead of a usage error #468

Description

@ondohotola

Version

zonemaster-cli v8.0.2, Zonemaster-Engine v9.0.0, Zonemaster-LDNS 5.1.0, NL NetLabs LDNS 1.9.2. Installed from CPAN on macOS. The code is unchanged on master as of 2026-09-02

To reproduce

zonemaster-cli --profile=/no/such/file.json --dump-profile

Actual result

Loading profile from /no/such/file.json.
read_file '/no/such/file.json' - open: No such file or directory at
  /Users/…/perl5/lib/perl5/Zonemaster/CLI.pm line 234.

Exit code 1.

Two problems

The message exposes an internal source path and line number rather than telling the user what to fix, and a bad command-line argument is reported as a generic error rather than a usage error.

Expected result

A localized message naming the option, and exit code 2 ($EXIT_USAGE_ERROR), consistent with how the same file already treats a bad --hints file and an invalid --sourceaddr4.

Cause

lib/Zonemaster/CLI.pm, in the --profile branch, calls read_file unguarded:

if ( $opt_profile ) {
    say $fh_diag __x( "Loading profile from {path}.", path => $opt_profile );
    my $json    = read_file( $opt_profile );
    my $foo     = Zonemaster::Engine::Profile->from_json( $json );

Compare the --hints branch a little further down, which does the right thing:

try {
    my $hints_text = read_file( $opt_hints ) // die "read_file failed\n";
    …
}
catch { $error = $_; };

if ( defined $error ) {
    print STDERR __x( "Error loading hints file: {message}", message => $error );
    return $EXIT_USAGE_ERROR;
}

The same treatment applied to --profile would fix it.

Note

It would also catch malformed JSON, which currently fails through Profile->from_json with a comparable raw error.

Two smaller points, if useful in the same change

  1. In the --hints branch, read_file( $opt_hints ) // die "read_file failed\n" is unreachable. File::Slurp's read_file croaks on failure in its default error mode rather than returning undef, so the // branch can never run. The surrounding try/catch is what actually catches the failure.
  2. Users commonly reach this by writing --profile=~/path/file.json. The shell does not perform tilde expansion after = in that position, so the literal ~ is passed through. This is arguably correct shell behavior rather than a CLI bug, but since the message currently gives no hint, a user has little to go on. Expanding a leading ~/ in file-path options, or naming it in the error text, would remove a common stumble.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-BugType: Bug in software or error in test case description

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions