Skip to content

fix: report missing input files without stack traces - #1036

Closed
He-Pin wants to merge 1 commit into
databricks:masterfrom
He-Pin:fix/cli-missing-input-file
Closed

He-Pin wants to merge 1 commit into
databricks:masterfrom
He-Pin:fix/cli-missing-input-file

Conversation

@He-Pin

@He-Pin He-Pin commented Jun 24, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Missing CLI input files and binding files could leak raw Java exceptions or stack traces instead of clean user-facing errors. Malformed paths could also escape the normal error path.

Scenario sjsonnet master this PR
Missing input file Java NoSuchFileException stack trace Opening input file: missing.jsonnet: no such file or directory
Missing binding file Java file/path exception Opening binding file: missing.jsonnet: no such file or directory
Malformed binding path Java InvalidPathException / IllegalArgumentException detail Opening binding file: <message>

Modification

  • Wrap entry file path construction and read in mainConfigured.
  • Wrap parseBindings calls for ext-vars and TLAs.
  • Catch NoSuchFileException, IOException, and malformed-path IllegalArgumentException in the relevant error paths.
  • Add JVM CLI regression tests for missing input files and malformed binding file paths.

Result

  • CLI input and binding file failures return exit code 1 with concise diagnostics.
  • Tests assert stderr content and verify Java exception class names are not leaked.
  • Existing stdin and --exec paths are unchanged.

Verification

  • ./mill --no-daemon 'sjsonnet.jvm[3.3.8].test' sjsonnet.MainTests
  • ./mill --no-daemon 'sjsonnet.jvm[3.3.8].checkFormat'

@He-Pin
He-Pin force-pushed the fix/cli-missing-input-file branch from 5cd11b6 to a23a523 Compare June 25, 2026 04:48
@He-Pin
He-Pin marked this pull request as draft June 25, 2026 17:57
@He-Pin
He-Pin marked this pull request as ready for review June 25, 2026 18:05
@He-Pin
He-Pin force-pushed the fix/cli-missing-input-file branch from 4e8555a to 56bc273 Compare June 25, 2026 19:04
Motivation: Missing or invalid input files and binding files could print stack traces.

Modification: Catch file and path errors at CLI boundaries and add regression coverage.

Result: Input failures now return user-facing errors without internal traces.
@He-Pin

He-Pin commented Jun 28, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by combined CLI PR #1032

@He-Pin He-Pin closed this Jun 28, 2026
stephenamar-db pushed a commit that referenced this pull request Jun 28, 2026
…y bindings (#1032)

## Motivation

Several CLI error paths leaked Java exception names
(`NoSuchFileException`, `InvalidPathException`, `upickle.core.Abort`) or
stack traces to end users. The `-V` short flag was ambiguously bound to
`--ext-str`, `--ext-code`, and `--tla-code`. The `--string` flag
produced internal errors for non-string results instead of a clean type
mismatch message. Binding file paths with invalid characters (e.g. null
bytes) were silently accepted. Reference implementations (C++ jsonnet,
go-jsonnet, jrsonnet) reserve `-V` exclusively for `--ext-str`.

This PR combines the following fixes into a single cohesive CLI
hardening change:

| Original PR | Fix |
| --- | --- |
| #1032 | Reserve `-V` exclusively for `--ext-str` |
| #1034 | Report undefined CLI binding env vars with clean error |
| #1035 | Make `--ext-str-file`/`--ext-code-file` lazy via
importstr/import |
| #1036 | Report missing input files without stack traces |
| #1038 | Report output file write failures cleanly |
| #1039 | Fix `--string` non-string error reporting |

## Modification

### Config / CLI parsing
- Remove `short = 'V'` from `--ext-code` and `--tla-code` `@arg`
annotations in `Config.scala`
- Keep `short = 'V'` on `--ext-str` only
- Update README help snapshot

### Error handling (`SjsonnetMainBase.scala`)
- Add `CliError` class with no stack trace for clean CLI error messages
- Add `handleRenderError` to wrap Jsonnet evaluation errors
- Add `handleWriteFile` to wrap file I/O errors with
C++/go-jsonnet-style messages
- Rewrite `parseBindings` to use `HashMap` with eager
`InvalidPathException` validation
- Make `--ext-str-file` and `--ext-code-file` lazy
(`importstr`/`import`) while still validating path syntax eagerly
- Add clean type error for `--string` with non-string results (matching
C++/go-jsonnet format)
- Wrap output file write and multi/yaml-stream render paths with error
handling

### Tests
- 18 new CLI integration tests covering all error paths
- `ConfigTests` verifies `-V` binds only to `--ext-str`
- 24 new test resource files (jsonnet inputs + golden outputs)

## Result

- All CLI errors produce clean messages matching C++/go-jsonnet
conventions
- `-V` binds only to `--ext-str`, matching reference implementations
- `--string` rejects non-string types with clear `expected string
result, got: <type>` error
- Malformed binding file paths fail eagerly with clean error
- Unused `--ext-str-file` bindings are lazy (file not read unless
referenced)
- 45/45 MainTests pass, 0 regressions in full test suite

## CLI Superset Status

sjsonnet is now a superset of go-jsonnet and C++ jsonnet CLI features,
with these extras:
- `--yaml-out`, `--yaml-debug`, `--debug-importer`, `--debug-stats`
- `--profile`, `--strict`, `--preserve-order`, `--indent`
- `--fatal-warnings`, `--throw-error-for-invalid-sets`
- `--max-stack`, `--max-parser-recursion-depth`
- `--reverse-jpaths-priority`, `--no-trailing-newline`
- `--broken-assertion-logic` (backwards compat)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant