Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Comments

Add WebSocketException and support for WS handlers#527

Closed
tiangolo wants to merge 3 commits intoKludex:masterfrom
tiangolo:websocket-exceptions
Closed

Add WebSocketException and support for WS handlers#527
tiangolo wants to merge 3 commits intoKludex:masterfrom
tiangolo:websocket-exceptions

Conversation

@tiangolo
Copy link
Contributor

Add WebSocketException and support for WS handlers.

Currently, if an exception is raised inside of a WebSocket endpoint, it bubbles, until a500 HTTP error is thrown.

This PR implements support for raising and handling exceptions inside of WebSocket endpoints.

It has default handlers using WebSocket codes from the specification.

It includes a genericWebSocketException comparable toHTTPException.

This would allow raising inside WebSocket endpoints, sub-functions, etc. And handling those errors in a custom manner. It might be used to, e.g. log WebSocket errors, customize a WebSocket closing code, etc.

Related issues:#483,#494


In FastAPI, this would allow using dependencies that can raise early in WebSocket routes (e.g. if the correct headers are not present) and other scenarios.

falsetru, jkamdjou, nkhitrov, xeor, paxcodes, arvid220u, umeshabhat, sebastienmascha, jhallard, alexted, and 31 more reacted with thumbs up emojijkamdjou, sebastienmascha, sakost, RuellePaul, vladimir-chernykh, alexanderomnix, karlbateman, abdalla19977, and mosynaq reacted with heart emojijkamdjou, sebastienmascha, RuellePaul, vladimir-chernykh, and mosynaq reacted with eyes emoji
@lovelydinosaur
Copy link
Contributor

Ah cool - interesting yup!

One thing for us to think about - are there currently any codepaths we're not thinking of where we're raising HTTPExceptions in a websocket context? Eg. Routing? Middleware?

@tiangolo
Copy link
ContributorAuthor

I just checked all the uses ofHTTPException and nope, at every point that it is raised it is exclusively for HTTP (e.g. inside ofRoute) or the scope is checked and theWebSocket is closed manually before (instead of) raising theHTTPException.


Nevertheless, I guess it's possible that in some scenarios people get confused and end up usingHTTPExceptions in WebSocket routes.

I could update the defaultHTTPException handler to check if it's receiving aRequest or aWebSocket and close the WebSocket in that case. What do you think?

@chbndrhnns
Copy link

Is there anything that prevents this PR from being merged?

Copy link
Contributor

@lovelydinosaurlovelydinosaur left a comment

Choose a reason for hiding this comment

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

Great stuff here - thanks!

I think my take here would be:

  • Let's defo include theWebSocketException handling. That's an obviously great addition.
  • Let's defo ensure that uvicorn issues 1011 websocket closes if it gets an exception during the websocket task and the connection is open. It needs to function gracefully in that case whatever. (There's an equivelent plain text 500 page for the http exception case.)
  • There's more complicated things to consider wrt. the websocket error handling. Perhaps let's remove that from this PR for now, so that we can discuss it in isolation from the handled-exceptions, which is far clearer.

chbndrhnns reacted with rocket emoji


class WebSocketException(Exception):
def __init__(self, code: int = status.WS_1008_POLICY_VIOLATION) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

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

I reckon we should probably havecode as a mandatory argument here, in line withHTTPException.

# 1011 indicates that a server is terminating the connection because
# it encountered an unexpected condition that prevented it from
# fulfilling the request.
await websocket.close(code=status.WS_1011_INTERNAL_ERROR)
Copy link
Contributor

@lovelydinosaurlovelydinosaurNov 7, 2019
edited
Loading

Choose a reason for hiding this comment

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

This is interesting...

We shouldn't reallyhave to do this, because the webserver's behaviorought to be in line with this anyway.
Ie. A higher priority task for us should be to ensure that uvicorn has equivelent handling, and will close the websocker with a 1011 code if it gets and exception, and the socket is still open.

We'd also want to check in this case that the websocket is in an open state. (The exceptioncould have been raised after the websocket close.) I think that means we'd want awebsocket_complete = False alongside the existingresponse_started = False, and track its state in the_send() function.

Copy link
Contributor

Choose a reason for hiding this comment

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

It's also not really clear if we want/need thisin any case - In the HTTP case, we can use the handler to issue an application-custom 500 page. In the websocket case there's really nothing available for us to do other than close the the connection, which the serverought to take care of anyways.

await self.app(scope, receive, _send)
except Exception as exc:
if not response_started:
if not response_started and scope["type"] == "http":
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's useif scope["type"] == "http" and not response_started

Kludex reacted with thumbs up emoji
@lovelydinosaur
Copy link
Contributor

Related, this PR makes me notice that wecould choose to alter our error handling, so that wealways run the http error handler (even if a response has already been started), it's just that weonly return that response if one has not already been started.

ifscope["type"]=="http":request=Request(scope)ifself.debug:# In debug mode, return traceback responses.response=self.debug_response(request,exc)elifself.handlerisNone:# Use our default 500 error handler.response=self.error_response(request,exc)else:# Use an installed 500 error handler.ifasyncio.iscoroutinefunction(self.handler):response=awaitself.handler(request,exc)else:response=awaitrun_in_threadpool(self.handler,request,exc)ifnotresponse_started:awaitresponse(scope,receive,send)

@luckydonald
Copy link

Hey guys. How's the status on this?

@Catastropha
Copy link

any good news?

@jkamdjou
Copy link

Would also love to see this merged.

@Catastropha
Copy link

Please merge, makes the code more beautiful

@tiangolo
Copy link
ContributorAuthor

I have to implement the code review, and that probably includes a PR to Uvicorn that I have to do carefully, I just haven't had time yet. But that's the reason. Hopefully I'll finish it soon.

Catastropha, nkhitrov, paxcodes, umeshabhat, urbanonymous, Nearata, four43, grossmj, black-night-heron, Satchitananda, and 4 more reacted with thumbs up emoji

@JayH5JayH5 added the websocketWebSocket-related labelSep 11, 2020
@remi-debette
Copy link

Hi! Is there any news on this?

jordan-cote, black-night-heron, nodarai, grossmj, RuellePaul, pnijhara, ofekkir, Satchitananda, wildengineer, RegulumDreik, and 3 more reacted with eyes emoji

@lewoudar
Copy link
Contributor

another ping to know it this pull request is still relevant

alexanderomnix, esenseial, baheckman, edaniszewski, hughsw, and luckydonald reacted with thumbs up emoji

@zljubisic
Copy link

Is there any news?

@Kludex
Copy link
Owner

Yeah, I talked to@tiangolo about taking the lead on this. I've rebased on#1263. Now I need to work on the uvicorn side.

There's no ETA for this. If someone wants this, implementing the uvicorn part is welcome (info about it on this PR).

@Kludex
Copy link
Owner

I'm closing this in favor of#1263.

@KludexKludex closed thisFeb 1, 2022
@tiangolotiangolo deleted the websocket-exceptions branchAugust 18, 2022 15:23
@urbanonymous
Copy link

Docs related tohttps://fastapi.tiangolo.com/advanced/websockets/ should be updated.

In the future, there will be a WebSocketException that you will be able to raise from anywhere, and add exception handlers for it. It depends on the [PR #527](https://github.com/encode/starlette/pull/527) in Starlette.

Kludex, martino87r, DeepBhat, committomaster, and naitokosuke reacted with thumbs up emoji

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

1 more reviewer

@lovelydinosaurlovelydinosaurlovelydinosaur requested changes

Reviewers whose approvals may not affect merge requirements

Assignees

No one assigned

Labels

websocketWebSocket-related

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

12 participants

@tiangolo@lovelydinosaur@chbndrhnns@luckydonald@Catastropha@jkamdjou@remi-debette@lewoudar@zljubisic@Kludex@urbanonymous@JayH5

[8]ページ先頭

©2009-2026 Movatter.jp