Skip to content

Conversation

@NathanFlurry
Copy link
Member

No description provided.

@vercel
Copy link

vercel bot commented Nov 10, 2025

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

Project Deployment Preview Comments Updated (UTC)
rivetkit-serverless Ready Ready Preview Comment Nov 10, 2025 1:14am
3 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
rivet-cloud Ignored Ignored Nov 10, 2025 1:14am
rivet-inspector Ignored Ignored Preview Nov 10, 2025 1:14am
rivet-site Ignored Ignored Preview Nov 10, 2025 1:14am

Copy link
Member Author

NathanFlurry commented Nov 10, 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 Nov 10, 2025

Code Review for PR #3429

Summary

This PR successfully refactors WebSocket protocol parsing logic by extracting duplicated code into a shared utility function parseWebSocketProtocols(). The refactoring reduces code duplication and improves maintainability.

✅ Positive Changes

  1. Good DRY principle application: Successfully eliminates ~50 lines of duplicated parsing logic across 3 files
  2. Clear function documentation: The new parseWebSocketProtocols() function has a clear JSDoc comment
  3. Consistent behavior: All three call sites now use the same parsing logic, reducing the risk of inconsistent behavior
  4. Improved maintainability: Future changes to WebSocket protocol parsing only need to happen in one place

🔍 Code Quality & Best Practices

Issue 1: Silent fallback behavior change in getRequestEncoding()

The PR changes getRequestEncoding() to return "json" as a default instead of throwing an error when the encoding header is missing:

// Before:
if (!encodingParam) {
    throw new errors.InvalidEncoding("undefined");
}

// After:
if (!encodingParam) {
    return "json";
}

Concerns:

  • This is a breaking behavioral change that affects error handling in common/router.ts:66 where the try-catch expects this function to throw
  • The comment mentions supporting "vanilla curl requests," but this changes existing error handling semantics
  • Could mask configuration issues where clients forget to send the encoding header

Recommendation: Consider one of these approaches:

  1. Keep the original error-throwing behavior and add a separate getRequestEncodingOrDefault() function for cases where a default is acceptable
  2. Add an optional parameter: getRequestEncoding(req: HonoRequest, defaultEncoding?: Encoding)
  3. If this change is intentional, update the error handler in common/router.ts to remove the now-unnecessary try-catch

Issue 2: Missing error handling in parseWebSocketProtocols()

const encoding = EncodingSchema.parse(encodingRaw);
const connParams = connParamsRaw ? JSON.parse(connParamsRaw) : undefined;

Both EncodingSchema.parse() and JSON.parse() can throw exceptions:

  • If encodingRaw is undefined or invalid, EncodingSchema.parse() will throw
  • If connParamsRaw contains invalid JSON, JSON.parse() will throw

Recommendation:

  • Use EncodingSchema.safeParse() like the original getRequestEncoding() function does, and throw an InvalidEncoding error with proper context
  • Wrap JSON.parse() in try-catch and throw an appropriate error (e.g., InvalidRequest or MalformedMessage)
  • This ensures consistent error messages for clients

Example:

const result = EncodingSchema.safeParse(encodingRaw);
if (!result.success) {
    throw new errors.InvalidEncoding(encodingRaw);
}
const encoding = result.data;

let connParams: unknown;
if (connParamsRaw) {
    try {
        connParams = JSON.parse(connParamsRaw);
    } catch (error) {
        throw new errors.MalformedMessage(`Invalid connection parameters: ${error}`);
    }
}

🐛 Potential Bugs

Bug 1: encodingRaw can be undefined

If no rivet_encoding. protocol is provided, encodingRaw will be undefined, causing EncodingSchema.parse(undefined) to throw without a clear error message.

Expected behavior: Should either:

  1. Throw InvalidEncoding("undefined") for consistency with the previous code
  2. Default to "json" if that's the intended new behavior

Bug 2: Inconsistent default behavior

  • getRequestEncoding() now defaults to "json" when missing
  • parseWebSocketProtocols() will throw when encoding is missing

This creates inconsistent behavior between HTTP requests and WebSocket connections.

🔒 Security Concerns

Low-severity concern: Missing URL decode validation

connParamsRaw = decodeURIComponent(
    protocol.substring(WS_PROTOCOL_CONN_PARAMS.length),
);

While decodeURIComponent() can throw on malformed input, the error isn't caught or handled gracefully. Consider wrapping in try-catch to provide a clearer error message.

⚡ Performance Considerations

No significant performance concerns. The refactoring actually improves performance slightly by:

  • Removing code duplication (smaller bundle size)
  • Using the same parsing logic (more consistent V8 optimization)

🧪 Test Coverage

Missing test coverage:

  • No unit tests found for the new parseWebSocketProtocols() function
  • No tests for getRequestEncoding() default behavior change

Recommendation:
Add tests covering:

  1. Valid protocol parsing with both encoding and connParams
  2. Valid protocol with encoding only
  3. Valid protocol with connParams only
  4. No protocols provided (should test error/default behavior)
  5. Invalid encoding value
  6. Malformed JSON in connParams
  7. Malformed URL encoding in connParams

📋 Suggested Changes

  1. Add proper error handling to parseWebSocketProtocols() (High priority)
  2. Reconsider the default behavior change in getRequestEncoding() (High priority)
  3. Add unit tests (Medium priority)
  4. Ensure consistent default behavior between HTTP and WebSocket paths (Medium priority)
  5. Add error handling for decodeURIComponent() (Low priority)

Summary Rating

  • Code Quality: ⚠️ Good with concerns - The refactoring is solid, but error handling needs improvement
  • Security: ✅ Acceptable - No major security issues
  • Performance: ✅ Good - Slight improvement
  • Test Coverage: ❌ Insufficient - Missing tests for new functionality

Overall, this is a good refactoring that improves code maintainability, but it needs stronger error handling and test coverage before merging.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 10, 2025

More templates

@rivetkit/actor

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/actor@3429

@rivetkit/cloudflare-workers

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/cloudflare-workers@3429

@rivetkit/core

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/core@3429

@rivetkit/db

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/db@3429

@rivetkit/framework-base

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/framework-base@3429

@rivetkit/next-js

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/next-js@3429

@rivetkit/react

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/react@3429

rivetkit

pnpm add https://pkg.pr.new/rivet-dev/rivet/rivetkit@3429

@rivetkit/sql-loader

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sql-loader@3429

@rivetkit/engine-runner

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@3429

@rivetkit/engine-runner-protocol

pnpm add https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@3429

commit: 52895aa

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