diff --git a/rio/cli/run_project/app_loading.py b/rio/cli/run_project/app_loading.py index 4a7d7ae1..b48d6692 100644 --- a/rio/cli/run_project/app_loading.py +++ b/rio/cli/run_project/app_loading.py @@ -1,9 +1,6 @@ import functools import html -import itertools -import os import sys -import traceback import types import typing as t from pathlib import Path @@ -14,8 +11,7 @@ import rio import rio.app_server.fastapi_server import rio.global_state -from ... import icon_registry, project_config -from .. import nice_traceback +from ... import icon_registry, nice_traceback, project_config class AppLoadError(Exception): @@ -27,24 +23,6 @@ class AppLoadError(Exception): return self.args[0] -def remove_rio_internals_from_traceback( - tb: list[traceback.FrameSummary], -) -> t.Sequence[traceback.FrameSummary]: - # Skip frames which are internal to rio (or libraries used by rio) until we - # hit the first non-rio frame. Then include everything. - rio_root = rio.__file__ - assert rio_root.endswith(os.sep + "__init__.py") - rio_root = rio_root.removesuffix(os.sep + "__init__.py") - - def predicate(frame: traceback.FrameSummary) -> bool: - return ( - frame.filename.startswith((rio_root, " None: + text = format_exception_revel(error, relpath=relpath) + revel.print(text) + @dataclasses.dataclass class FormatStyle: @@ -60,6 +79,24 @@ def _handle_syntax_error(err: SyntaxError) -> traceback.FrameSummary: ) +def remove_rio_internals_from_traceback( + tb: list[traceback.FrameSummary], +) -> t.Sequence[traceback.FrameSummary]: + # Skip frames which are internal to rio (or libraries used by rio) until we + # hit the first non-rio frame. Then include everything. + rio_root = rio.__file__ + assert rio_root.endswith(os.sep + "__init__.py") + rio_root = rio_root.removesuffix(os.sep + "__init__.py") + + def predicate(frame: traceback.FrameSummary) -> bool: + return ( + frame.filename.startswith((rio_root, " None: """ Format a single exception and write it to the output stream. @@ -81,7 +115,7 @@ def _format_single_exception_raw( if isinstance(err, SyntaxError): tb_list.append(_handle_syntax_error(err)) - tb_list = preprocess_traceback(tb_list) + tb_list = remove_rio_internals_from_traceback(tb_list) # TODO: Add special handling for recursion errors. Instead of printing the # same frame 1000 times, print a message like "Last 5 frames repeated 200 @@ -164,9 +198,6 @@ def format_exception_raw( *, style: FormatStyle, relpath: Path | None = None, - preprocess_traceback: t.Callable[ - [list[traceback.FrameSummary]], t.Sequence[traceback.FrameSummary] - ] = lambda tb: tb, ) -> str: """ Format an exception into a pretty string with the given style. @@ -198,7 +229,6 @@ def format_exception_raw( include_header=include_header, style=style, relpath=relpath, - preprocess_traceback=preprocess_traceback, ) # Format @@ -211,9 +241,6 @@ def format_exception_revel( err: BaseException, *, relpath: Path | None = None, - preprocess_traceback: t.Callable[ - [list[traceback.FrameSummary]], t.Sequence[traceback.FrameSummary] - ] = lambda tb: tb, ) -> str: """ Format an exception using revel's styling. @@ -237,7 +264,6 @@ def format_exception_revel( err, style=style, relpath=relpath, - preprocess_traceback=preprocess_traceback, ) @@ -245,9 +271,6 @@ def format_exception_html( err: BaseException, *, relpath: Path | None = None, - preprocess_traceback: t.Callable[ - [list[traceback.FrameSummary]], t.Sequence[traceback.FrameSummary] - ] = lambda tb: tb, ) -> str: """ Format an exception into HTML with appropriate styling. @@ -271,7 +294,6 @@ def format_exception_html( err, style=style, relpath=relpath, - preprocess_traceback=preprocess_traceback, ) # HTML-ify newlines diff --git a/rio/session.py b/rio/session.py index 2166e278..a72a0bab 100644 --- a/rio/session.py +++ b/rio/session.py @@ -16,7 +16,9 @@ import typing as t import weakref from datetime import tzinfo +import introspection import ordered_set +import revel import starlette.datastructures import unicall import uniserde @@ -33,6 +35,7 @@ from . import ( fills, global_state, inspection, + nice_traceback, routing, serialization, session_attachments, @@ -864,9 +867,9 @@ window.resizeTo(screen.availWidth, screen.availHeight); await result # Display and discard exceptions - except Exception: - print("Exception in event handler:") - traceback.print_exc() + except Exception as error: + revel.error("Exception in event handler:") + nice_traceback.print_exception(error) if refresh: await self._refresh() @@ -2318,6 +2321,7 @@ window.history.{method}(null, "", {json.dumps(relative_url)}) new_name="file_types", ) @deprecations.deprecated(since="0.10", replacement=pick_file) + @introspection.set_signature(pick_file) async def file_chooser( self, *args,