Skip to content

Commit 205e74b

Browse files
committed
✨ Add sentry integration
1 parent 6a86317 commit 205e74b

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ dependencies = [
3939
"httpx >= 0.27.0,< 0.28.0",
4040
"rich-toolkit >= 0.12.0",
4141
"pydantic >= 1.6.1",
42+
"sentry-sdk",
4243
]
4344

4445
[project.optional-dependencies]

src/fastapi_cloud_cli/cli.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,70 @@
1+
from types import TracebackType
2+
from typing import Callable, Optional, Type
3+
4+
import sentry_sdk
15
import typer
6+
from sentry_sdk.integrations import Integration
7+
from sentry_sdk.utils import (
8+
capture_internal_exceptions,
9+
event_from_exception,
10+
)
211

312
from .commands.deploy import deploy
413
from .commands.env import env_app
514
from .commands.login import login
615
from .commands.whoami import whoami
716

8-
app = typer.Typer(rich_markup_mode="rich")
17+
ExceptionHandler = Callable[
18+
[Type[BaseException], BaseException, Optional[TracebackType]], None
19+
]
20+
21+
22+
def _make_excepthook(
23+
old_excepthook: ExceptionHandler,
24+
) -> ExceptionHandler:
25+
def sentry_sdk_excepthook(
26+
exc_type: Type[BaseException],
27+
exc_value: BaseException,
28+
tb: Optional[TracebackType],
29+
) -> None:
30+
integration = sentry_sdk.get_client().get_integration(TyperIntegration)
31+
32+
if integration is None:
33+
return old_excepthook(exc_type, exc_value, tb)
34+
35+
with capture_internal_exceptions():
36+
event, hint = event_from_exception(
37+
(exc_type, exc_value, tb),
38+
client_options=sentry_sdk.get_client().options,
39+
mechanism={"type": "excepthook", "handled": False},
40+
)
41+
sentry_sdk.capture_event(event, hint=hint)
42+
43+
return old_excepthook(exc_type, exc_value, tb)
44+
45+
return sentry_sdk_excepthook
46+
47+
48+
def patch_typer() -> None:
49+
typer.main.except_hook = _make_excepthook(typer.main.except_hook) # type: ignore
50+
51+
52+
class TyperIntegration(Integration):
53+
identifier = "typer"
54+
55+
@staticmethod
56+
def setup_once() -> None:
57+
patch_typer()
58+
59+
60+
sentry_sdk.init(
61+
dsn="https://230250605ea4b58a0b69c768e9ec1168@o4506985151856640.ingest.us.sentry.io/4508449198899200",
62+
traces_sample_rate=1.0,
63+
integrations=[TyperIntegration()],
64+
)
65+
66+
67+
app = typer.Typer()
968

1069

1170
# TODO: use the app structure

0 commit comments

Comments
 (0)