Skip to content

Conversation

@NathanFlurry
Copy link
Member

No description provided.

@vercel
Copy link

vercel bot commented Dec 23, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
rivet-site Ready Ready Preview, Comment Jan 2, 2026 11:37pm
rivetkit-serverless Error Error Jan 2, 2026 11:37pm
2 Skipped Deployments
Project Deployment Review Updated (UTC)
rivet-cloud Ignored Ignored Jan 2, 2026 11:37pm
rivet-inspector Ignored Ignored Preview Jan 2, 2026 11:37pm

Copy link
Member Author

NathanFlurry commented Dec 23, 2025

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more


How to use the Graphite Merge Queue

Add the label merge-queue to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@claude
Copy link

claude bot commented Dec 23, 2025

PR Review: RIVET_EXPOSE_ERRORS Environment Variable

Summary

This PR introduces the RIVET_EXPOSE_ERRORS environment variable to control whether internal error details are exposed to clients, complementing the existing NODE_ENV=development behavior. The implementation is straightforward and includes helpful documentation.


✅ Strengths

  1. Good Security Practice: The feature correctly defaults to hiding internal errors in production, only exposing them when explicitly enabled
  2. Clear Documentation: The website/src/content/docs/actors/errors.mdx additions provide excellent guidance with warnings about security implications
  3. Consistent Implementation: The flag is consistently applied in both locations where errors are deconstructed (WebSocket and HTTP endpoints)
  4. Appropriate JSDoc: The comment in router-endpoints.ts:201-204 clearly explains the function's behavior

🔍 Code Quality Observations

1. Missing Return Value Handling (Minor)

In getEnvUniversal, if neither Deno nor process are available, the function returns undefined implicitly. This is handled correctly in the boolean checks, but could be more explicit:

// Current at utils.ts:43-50
export function getEnvUniversal(key: string): string | undefined {
	if (typeof Deno \!== "undefined") {
		return Deno.env.get(key);
	} else if (typeof process \!== "undefined") {
		return process.env[key];
	}
	// Implicit undefined return
}

Recommendation: Consider adding an explicit return undefined; for clarity, though this is a pre-existing pattern.

2. Duplicate Logic (Minor)

The same boolean condition appears in two places:

  • actor/router-endpoints.ts:206-209
  • actor/protocol/old.ts:291-292

Current:

// In router-endpoints.ts
export function getRequestExposeInternalError(_req: Request): boolean {
	return (
		getEnvUniversal("RIVET_EXPOSE_ERRORS") === "1" ||
		getEnvUniversal("NODE_ENV") === "development"
	);
}

// In protocol/old.ts
getEnvUniversal("RIVET_EXPOSE_ERRORS") === "1" ||
	getEnvUniversal("NODE_ENV") === "development",

Issue: The protocol/old.ts location duplicates the logic inline instead of using the getRequestExposeInternalError function.

Recommendation: Refactor to use the helper function consistently:

// In protocol/old.ts:291-292
getRequestExposeInternalError(undefined as any), // or pass actual request if available

However, I notice getRequestExposeInternalError takes a Request parameter (currently unused with _req). If you plan to make this request-specific in the future, the current approach is fine. Otherwise, consider renaming to shouldExposeInternalErrors() and removing the unused parameter.

3. Potential Performance Consideration (Very Minor)

The getEnvUniversal function is called twice per error in both implementations. While environment variable access is typically fast, you could micro-optimize by calling once and storing the result:

export function getRequestExposeInternalError(_req: Request): boolean {
	const exposeErrors = getEnvUniversal("RIVET_EXPOSE_ERRORS");
	const nodeEnv = getEnvUniversal("NODE_ENV");
	return exposeErrors === "1" || nodeEnv === "development";
}

This is likely premature optimization given that environment variables are typically cached by the runtime.


🧪 Test Coverage

Observation: No test files were modified or added for this functionality.

Recommendations:

  1. Add unit tests for getRequestExposeInternalError:
    • Returns true when RIVET_EXPOSE_ERRORS=1
    • Returns true when NODE_ENV=development
    • Returns false in production with no override
    • Handles both flags being set
  2. Add integration tests verifying that:
    • Internal errors are masked in production
    • Internal errors are exposed when flag is set
    • Error logging still occurs server-side regardless of flag

🔒 Security Review

Status: ✅ No security concerns

  • The feature correctly defaults to secure behavior (hiding errors)
  • Documentation prominently warns against production use
  • The implementation doesn't introduce new attack vectors
  • Error details are still logged server-side for debugging

📝 Documentation Quality

The documentation additions in errors.mdx are excellent:

  • ✅ Clear warning about production use
  • ✅ Explains when errors are exposed
  • ✅ Provides code examples
  • ✅ Reminds users to check server logs

🎯 Recommendations Summary

Must Fix:

  • None - the PR is functional and safe

Should Consider:

  1. Add unit tests for the new functionality
  2. Consolidate duplicate logic in protocol/old.ts to use getRequestExposeInternalError
  3. Consider renaming getRequestExposeInternalError to remove the unused _req parameter (unless future plans exist)

Nice to Have:

  • Explicit return undefined; in getEnvUniversal
  • Micro-optimization to call getEnvUniversal only once per check

✅ Approval Status

Approved with suggestions - The core implementation is solid and secure. The suggestions above are minor improvements that could be addressed in follow-up work. The lack of tests is the most significant gap, but doesn't block merging for a relatively simple feature.

Great work on the clear documentation! 🎉

@jog1t jog1t force-pushed the 12-23-chore_rivetkit_specialize_context_types_for_better_compiler_errors branch from e4a1e83 to f96b9d8 Compare January 2, 2026 23:33
@jog1t jog1t force-pushed the 12-23-chore_rivetkit_rivet_expose_errors_ branch from 88139ac to 4fd5ce8 Compare January 2, 2026 23:33
@NathanFlurry NathanFlurry force-pushed the 12-23-chore_rivetkit_rivet_expose_errors_ branch from 4fd5ce8 to 88139ac Compare January 2, 2026 23:59
@NathanFlurry NathanFlurry force-pushed the 12-23-chore_rivetkit_specialize_context_types_for_better_compiler_errors branch from f96b9d8 to e4a1e83 Compare January 2, 2026 23:59
@jog1t jog1t force-pushed the 12-23-chore_rivetkit_specialize_context_types_for_better_compiler_errors branch from e4a1e83 to f96b9d8 Compare January 3, 2026 00:05
@jog1t jog1t force-pushed the 12-23-chore_rivetkit_rivet_expose_errors_ branch from 88139ac to 4fd5ce8 Compare January 3, 2026 00:05
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.

2 participants