Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[protocolv2] Handle invalid requests and internal server errors #203

Merged
merged 1 commit into from
Jun 20, 2024

Conversation

masad-frost
Copy link
Member

@masad-frost masad-frost commented Jun 15, 2024

Why

Clients can send invalid requests for many reasons, most commonly due to backwards incompatible server changes, server should handle those and send back a stream abort with it.

What changed

  • Introduced INTERNAL_RIVER_ERROR code since some of the errors are invariant violations on the server
  • Split out stream request validation from stream handling
  • When we see a bad request, we send INVALID_REQUEST code with an abort bit
  • Made tracing createHandlerSpan accept tracing fields explicitly instead of a transport message

some more changes that I'll note inline

@masad-frost masad-frost requested a review from a team as a code owner June 15, 2024 03:33
@masad-frost masad-frost requested review from jackyzha0 and removed request for a team June 15, 2024 03:33
@@ -399,10 +395,6 @@ class RiverServer<Services extends AnyServiceSchemaMap>

const onHandlerError = (err: unknown, span: Span) => {
const errorMsg = coerceErrorString(err);
this.log?.error(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stopped logging here, it's an application-level error, clients can choose to log this

@@ -558,11 +551,11 @@ class RiverServer<Services extends AnyServiceSchemaMap>

break;
default:
this.log?.warn(
this.log?.error(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

promoted to error, this should never happen.

this.transport.sessionHandshakeMetadata.get(session);
if (!sessionMetadata) {
const errMessage = `session doesn't have handshake metadata`;
this.log?.error(errMessage, {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

promoted this from warn to error, as it's an internal error, we should never hit this in theory.

router/server.ts Show resolved Hide resolved

if (!initMessage.serviceName) {
const errMessage = `missing service name in stream open message`;
this.log?.warn(errMessage, {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

demoted to warn, it's a client problem.


if (!Value.Check(procedure.init, initMessage.payload)) {
const errMessage = `procedure init failed validation`;
this.log?.warn(errMessage, {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

demoted to warn, it's a client problem.

validationErrors.push(...Value.Errors(procedure.input, msg.payload));
}

this.log?.warn(errMessage, {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

demoted to warn, it's a client problem.

@@ -315,23 +287,47 @@ class RiverServer<Services extends AnyServiceSchemaMap>
}

if (inputReader.isClosed()) {
this.log?.error('Received message after input stream is closed', {
this.log?.warn('Received message after input stream is closed', {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

demoted to warn, it's a client problem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this an invariant violation / should we add that as a tag?

@@ -293,7 +264,8 @@ class RiverServer<Services extends AnyServiceSchemaMap>
code: ABORT_CODE,
message: 'Stream aborted, client sent invalid payload',
});
this.log?.error('Got stream abort without a valid protocol error', {
this.log?.warn('Got stream abort without a valid protocol error', {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

demoted to warn, it's a client problem.

*/
session: Session<Connection>; // TODO: only expose a subset interface of session
from: TransportClientId;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels like the only thing a service implementer would might need from a session

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

*/
session: Session<Connection>; // TODO: only expose a subset interface of session
from: TransportClientId;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

tracing/index.ts Show resolved Hide resolved
@@ -315,23 +287,47 @@ class RiverServer<Services extends AnyServiceSchemaMap>
}

if (inputReader.isClosed()) {
this.log?.error('Received message after input stream is closed', {
this.log?.warn('Received message after input stream is closed', {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this an invariant violation / should we add that as a tag?

...loggingMetadata,
clientId: this.transport.clientId,
transportMessage: msg,
validationErrors,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here: maybe we want to tag this with invariant violation?

router/server.ts Show resolved Hide resolved
router/server.ts Show resolved Hide resolved
Base automatically changed from fm-add-cleanup to protocolv2 June 18, 2024 00:48
@masad-frost masad-frost merged commit 791a3c4 into protocolv2 Jun 20, 2024
3 checks passed
@masad-frost masad-frost deleted the fm-invalid-requests branch June 20, 2024 17:39
masad-frost added a commit that referenced this pull request Jun 20, 2024
## Why

Clients can send invalid requests for many reasons, most commonly due to
backwards incompatible server changes, server should handle those and
send back a stream abort with it.

## What changed

- Introduced `INTERNAL_RIVER_ERROR` code since some of the errors are
invariant violations on the server
- Split out stream request validation from stream handling
- When we see a bad request, we send `INVALID_REQUEST` code with an
abort bit
- Made tracing `createHandlerSpan` accept tracing fields explicitly
instead of a transport message

some more changes that I'll note inline
masad-frost added a commit that referenced this pull request Jun 24, 2024
## Why

Clients can send invalid requests for many reasons, most commonly due to
backwards incompatible server changes, server should handle those and
send back a stream abort with it.

## What changed

- Introduced `INTERNAL_RIVER_ERROR` code since some of the errors are
invariant violations on the server
- Split out stream request validation from stream handling
- When we see a bad request, we send `INVALID_REQUEST` code with an
abort bit
- Made tracing `createHandlerSpan` accept tracing fields explicitly
instead of a transport message

some more changes that I'll note inline
masad-frost added a commit that referenced this pull request Jun 24, 2024
## Why

Clients can send invalid requests for many reasons, most commonly due to
backwards incompatible server changes, server should handle those and
send back a stream abort with it.

## What changed

- Introduced `INTERNAL_RIVER_ERROR` code since some of the errors are
invariant violations on the server
- Split out stream request validation from stream handling
- When we see a bad request, we send `INVALID_REQUEST` code with an
abort bit
- Made tracing `createHandlerSpan` accept tracing fields explicitly
instead of a transport message

some more changes that I'll note inline
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.

None yet

2 participants