Error dialog
ui.error_dialog(info, on_close) shows an error in a dialog: its message, where it happened, the file and line it comes from and the traceback in a read-only editor, where any part can be selected and copied. Its buttons copy the whole report, go to the origin (on_go_to, labeled go_to_label), show it among the logs (on_logs) and close. more adds a line saying how many other errors came after it. info is a ui.ErrorInfo; show the dialog with a Dialog layer.
ui.error_dialog · Category: Dialogs · Full reference →


def average(values): return sum(values) / len(values)
try: average([])except ZeroDivisionError as err: info = ui.ErrorInfo.from_exception(err, where="Totals")
ui.dialog_layer(main_view(), ui.error_dialog(info, on_close, on_go_to=on_go_to, on_logs=on_logs, width=620))When to use
Section titled “When to use”- When something the user asked for fails (saving, exporting, running a script) and the details matter.
- From the Details button of an Error boundary.
- For a short message without a traceback, use an Alert with
kind="error".
import pyzed as pzfrom pyzed import ui
class Notes(pz.App): def __init__(self): self.error = None
def save(self): try: write_notes(self.notes) except OSError as err: self.error = ui.ErrorInfo.from_exception(err, where="Save")
def close_error(self): self.error = None
def view(self): dialog = ui.error_dialog(self.error, self.close_error) if self.error else None return ui.dialog_layer(self.page(), dialog, on_dismiss=self.close_error)Variants
Section titled “Variants”Options
Section titled “Options”Without a traceback the dialog leaves out the code box, as with an ErrorInfo you build yourself.


Code
def average(values): return sum(values) / len(values)
try: average([])except ZeroDivisionError as err: info = ui.ErrorInfo.from_exception(err, where="Totals")
ui.error_dialog(info, on_close, width=480)

on_go_to=, go_to_label=Code
def average(values): return sum(values) / len(values)
try: average([])except ZeroDivisionError as err: info = ui.ErrorInfo.from_exception(err, where="Totals")
ui.error_dialog(info, on_close, on_go_to=on_go_to, go_to_label="Open app.py", width=480)

on_logs=Code
def average(values): return sum(values) / len(values)
try: average([])except ZeroDivisionError as err: info = ui.ErrorInfo.from_exception(err, where="Totals")
ui.error_dialog(info, on_close, on_logs=on_logs, width=480)

more=2Code
def average(values): return sum(values) / len(values)
try: average([])except ZeroDivisionError as err: info = ui.ErrorInfo.from_exception(err, where="Totals")
ui.error_dialog(info, on_close, more=2, width=480)

title=Code
def average(values): return sum(values) / len(values)
try: average([])except ZeroDivisionError as err: info = ui.ErrorInfo.from_exception(err, where="Totals")
ui.error_dialog(info, on_close, title="The totals could not be computed", width=480)

Code
info = ui.ErrorInfo("PermissionError", "[Errno 13] Permission denied: 'notes.md'", where="Save")ui.error_dialog(info, on_close, width=480)Events
Section titled “Events”Error dialog has 3 events of its own, listed below. Like every widget it also has the 18 common events (click, double_click, right_click, mouse_enter, drag, key_down, resize…), attached with .on(...): see Events and Events of every component.
| Event | Handler gets | When |
|---|---|---|
on_close |
() |
Close button and Escape. |
on_go_to |
() |
Adds the go-to button (open the file at the line). |
on_logs |
() |
Adds a Show in Logs button. |
Handler gets is what Pyzed passes to your callable: () means nothing. Any handler can also be a message (a value that is not callable), which goes to update().
Handling the events
Section titled “Handling the events”The same events written three ways. Imperative: methods of the app change self. Declarative: the handlers produce messages and one update() decides. Functional: a pure function draws an immutable state and asks for changes with set_state(...). See Imperative, declarative and functional.
class Notes(pz.App): def __init__(self): try: open("/no/such/file") except OSError as err: self.error = ui.ErrorInfo.from_exception(err, where="Open")
def close(self): # on_close: the button and Escape self.error = None
def view(self): dialog = ui.error_dialog(self.error, self.close, on_go_to=lambda: print("go to", self.error.origin), # adds Go to on_logs=lambda: print("show logs")) if self.error else None return ui.dialog_layer(main_view(), dialog, on_dismiss=self.close)class Notes(pz.App): error = ui.ErrorInfo("FileNotFoundError", "No such file: notes.txt")
def update(self, message): match message: case "close": self.error = None case "logs": print("show logs")
def view(self): dialog = ui.error_dialog(self.error, "close", on_logs="logs") if self.error else None return ui.dialog_layer(main_view(), dialog, on_dismiss="close")from dataclasses import dataclass
@dataclass(frozen=True)class State: error: object = ui.ErrorInfo("FileNotFoundError", "No such file: notes.txt")
def view(state, set_state): close = lambda: set_state(error=None) dialog = ui.error_dialog(state.error, close) if state.error else None return ui.dialog_layer(main_view(), dialog, on_dismiss=close)Properties and API
Section titled “Properties and API”ui.error_dialog
Section titled “ui.error_dialog”error_dialog( info, on_close, *, title=None, on_go_to=None, go_to_label=None, on_logs=None, more=0, width=680, theme=None,)A dialog with an error: its message, where it happened, the file and line it comes from and the traceback in a read-only editor (select and copy any part), with buttons to copy everything, go to the origin, see it among the logs and close. Show it with ui.dialog_layer or ui.layer.
| Property | Default | Description |
|---|---|---|
info |
required | A ui.ErrorInfo. |
title |
None |
Heading (“Something went wrong”). |
go_to_label |
None |
Its text (“Go to source”). |
more |
0 |
How many other errors came after it (a line says so). |
width |
680 |
Width in pixels or a modal size. |
theme |
None |
Theme override. |
Events: on_close, on_go_to, on_logs (events).