fix(sendFile): surface resolved path in "No such file" error; clarify no auto-versioning (#257)#330
Open
naorpeled wants to merge 2 commits into
Conversation
… no auto-versioning (jeremydaly#257) Issue jeremydaly#257 reported that a `/:v/schema.json` route returned `{"error":"No such file"}` at `/v1/schema.json` and asked for an option to disable "versioning". Investigation showed lambda-api has no version routing/stripping — `/:v/schema.json` already matches `/v1/schema.json` and captures `req.params.v === "v1"`. The error actually came from `res.sendFile()` throwing ENOENT in the reporter's own handler; the terse, pathless message is what led to the misdiagnosis. - sendFile ENOENT errors now include the resolved path (e.g. `No such file: ./test-missing.txt`) so the real cause is obvious. - Add __tests__/versioning.unit.js locking in literal version-segment routing and documenting the `base: 'v1'` + leading `:param` collision caveat. - Update the two existing sendFile/download "Missing file" assertions. - Document in the README that lambda-api performs no automatic version handling, and how `res.sendFile(path, { root })` resolves paths.
3b77322 to
fb470a9
Compare
There was a problem hiding this comment.
Pull request overview
This PR addresses confusion from issue #257 by clarifying that lambda-api does not do any automatic “version” path handling, and by making res.sendFile() missing-file errors more self-explanatory so they aren’t misread as routing failures.
Changes:
- Update
sendFile()ENOENT handling to include the missing path in the"No such file"error message. - Add a new regression test suite verifying version-like segments (e.g.
/v1/...) are matched literally, plus a documentedbase: 'v1'caveat. - Update README guidance and adjust existing unit tests to the new error string.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/lib/response.js | Changes ENOENT error message emitted by sendFile() to include a path string. |
| README.md | Documents that there is no automatic version stripping and clarifies sendFile({ root }) path resolution. |
| tests/versioning.unit.js | Adds regression tests for literal matching of version-like segments and base + leading :param collision behavior. |
| tests/sendFile.unit.js | Updates missing-file assertion to match the new error message. |
| tests/download.unit.js | Updates missing-file assertion to match the new error message. |
…all, add v2/ALB versioning tests - response.js: strip opts.root prefix and reduce absolute paths to basename in the client-visible "No such file" error to avoid leaking server paths (e.g. /var/task/...); full e.path is still preserved on FileError for logs - README: note sendFile root+path is literal concatenation and needs a trailing/leading slash to avoid ./static + file.txt -> ./staticfile.txt - versioning.unit.js: assert version-like segments match literally for API Gateway v2 (rawPath) and ALB events, not just v1 - sendFile.unit.js: regression tests for absolute-root and absolute-path sanitization
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #257.
Background
#257 reported that a route
/:v/schema.jsonreturned{"error":"No such file"}when hitting/v1/schema.json, and asked for an option to disable versioning.Investigation showed the premise doesn't hold: lambda-api has no automatic version routing or stripping — in the current code or anywhere in git history. Route matching (
src/lib/request.js) is plain segment-by-segment traversal. Reproduced against the reporter's exact setup:The
"No such file"was not a routing error — it's emitted byres.sendFile()onENOENTin the reporter's own handler (they most likely passedreq.path=/v1/schema.jsontosendFile, so the full path was looked up on disk). Because the error message was terse and pathless, it was easy to misread as a "versioning" problem.So rather than add a no-op flag, this PR fixes the actual pain and locks in the behavior.
Changes
src/lib/response.js—sendFileENOENTerrors now include the resolved path, e.g.No such file: ./test-missing.txt, so the real cause is self-evident.FileErroralready carriede.path; it just never reached the message.__tests__/versioning.unit.js(new) — regression tests proving version-like segments route literally (/v1/schema.json→params.v === 'v1'), a non-version segment behaves identically, an extra segment still 404s, and documents thebase: 'v1'+ leading:paramcollision caveat (→ 405).__tests__/sendFile.unit.js,__tests__/download.unit.js— updated the two "Missing file" assertions to the new message.README.md— documented that lambda-api does no automatic version handling, thatbase: 'v1'collides with a leading:param(prefer a non-version base +register({ prefix })), and howres.sendFile(path, { root })resolves paths.Heads-up for review
The error-message change surfaces the file path in the HTTP error body. It's helpful for debugging and mirrors Node's own ENOENT, but it is a minor change to a public error string — happy to make it opt-in or revert that part if you'd prefer it stay terse.
Verification
Full suite green:
npm run build+tsd+ 489 passed / 4 skipped across 28 suites. Prettier + ESLint clean on touched files.