How to handle worker exceptions? #3174
-
Sorry if I'm missing something obvious, but I'm still unclear how to handle worker exceptions even after reading through the Workers guide in the docs. I've created a simple example below which logs the HTTPX response after submitting a URL. How would you display an error message if HTTPX raises an exception? Many thanks in advance for any advice! import httpx
from textual import on, work
from textual.app import App, ComposeResult
from textual.widget import Widget
from textual.widgets import Input, RichLog
class HttpxResponse(Widget):
def compose(self) -> ComposeResult:
yield RichLog(highlight=True, auto_scroll=False)
def update(self, html: str) -> None:
log = self.query_one(RichLog)
log.clear()
log.write(html)
def load_url(self, url: str) -> None:
self._load_url(httpx.URL(url))
@work(
exclusive=True,
# exit_on_error=False,
)
async def _load_url(self, url: httpx.URL) -> None:
async with httpx.AsyncClient() as client:
resp = await client.get(url)
self.update(resp.text)
class ExampleApp(App):
CSS = """
Input {
dock: top;
}
"""
def compose(self) -> ComposeResult:
yield Input(placeholder="Enter web address")
yield HttpxResponse()
@on(Input.Submitted)
def on_input_submitted(self, event: Input.Submitted) -> None:
if not event.value:
return
html = self.query_one(HttpxResponse)
try:
html.load_url(event.value)
except httpx.HTTPError:
html.update(f"Oops! Something went wrong loading {event.value}!")
if __name__ == "__main__":
app = ExampleApp()
app.run() |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
When you call a method decorated by However, if you wait for the worker in a message handler you will prevent further messages from being handled. To keep things responsive you can respond to worker events. That said, it is generally simpler to handle any exceptions within the worker itself. i.e. catch |
Beta Was this translation helpful? Give feedback.
When you call a method decorated by
@work
it will return the Worker object. You can callwait()
on that worker object, which will wait for it to finished, and re-raise any exceptions.However, if you wait for the worker in a message handler you will prevent further messages from being handled. To keep things responsive you can respond to worker events.
That said, it is generally simpler to handle any exceptions within the worker itself. i.e. catch
httpx.HTTPError
inside_load_url
.