Skip to content

Improve error handling#76

Open
aryan-25 wants to merge 2 commits intoswift-server:mainfrom
aryan-25:improve-request-error-handling
Open

Improve error handling#76
aryan-25 wants to merge 2 commits intoswift-server:mainfrom
aryan-25:improve-request-error-handling

Conversation

@aryan-25
Copy link
Copy Markdown
Collaborator

@aryan-25 aryan-25 commented Apr 1, 2026

Motivation:

The serveInsecureHTTP1_1 and serveSecureUpgrade methods listen for incoming activity on the server channel and dispatch connections/requests to child tasks in order to process concurrently. However, these methods use a withThrowingDiscardingTaskGroup, and call many throwing functions from within the task group.

Since a discarding task group implicitly cancels all child tasks as soon as an error is encountered in any child task, we should carefully reason about and handle all errors that could arise within the task group.

Modifications:

  • Addressed comments raised in Fix request error handling #71. This included removing the redundant throw keyword from the handleRequestChannel declaration.

  • Refactored serveInsecureHTTP1_1 and serveSecureUpgrade (and associated methods) to handle errors more explicitly without propagating them up to the parent task group. As a result, it was then possible to replace withThrowingDiscardingTaskGroup with withDiscardingTaskGroup.

Result:

Better error handling.

Motivation:

The `serveInsecureHTTP1_1` and `serveSecureUpgrade` methods listen for incoming activity on the server channel and dispatch connections/requests to child tasks in order to process concurrently. However, these methods use a `withThrowingDiscardingTaskGroup`, and call many `throw`ing functions from within the task group.

Since a `discarding` task group implicitly cancels *all* child tasks as soon as an error is encountered in *any* child task, we should carefully reason about and handle all errors that could arise within the task group.

Modifications:

- Removed the redundant `throw` keyword from the `handleRequestChannel` method declaration.

- Refactored `serveInsecureHTTP1_1` and `serveSecureUpgrade` to handle errors more explicitly without propagating them up to the parent task group. As a result, it was then possible to replace `withThrowingDiscardingTaskGroup` with `withDiscardingTaskGroup`.

Result:

Better error handling.
@aryan-25 aryan-25 requested review from fabianfett and gjcairo April 1, 2026 12:19
@aryan-25 aryan-25 added the 🔨 semver/patch No public API change. label Apr 1, 2026
handler: handler
)
try await serverChannel.executeThenClose { inbound in
let inboundConnectionIterationError = await withDiscardingTaskGroup { group -> (any Error)? in
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why can't we just use withThrowingDiscardingTaskGroup here? The only error we're throwing is the one coming from iterating inbound.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is primarily to make it explicit that if you call a throwing function from within the body of the task group, the error must be handled directly rather than letting it propagate upwards and resulting in active tasks in the group being cancelled.

Currently iterating on inbound is the only source of a potential error, but if this was a withThrowingDiscardingTaskGroup then in the future we could inadvertently introduce a call to a throwing function without the compiler warning us.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Could we add some comment here (and in the other func) explaining this rationale? I am not convinced just doing things this way would prevent a future change from changing the behaviour unless it's more documented.

}
}
try await serverChannel.executeThenClose { inbound in
let inboundConnectionIterationError = await withDiscardingTaskGroup { connectionGroup -> (any Error)? in
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Similarly, I don't see why this is clearer than just using a throwing task group and throwing where appropriate?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Discussed here.

@aryan-25 aryan-25 requested a review from gjcairo April 2, 2026 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 semver/patch No public API change.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants