Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(2) Move capture_* from Hub to Client #2555

Merged
merged 32 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
f2a4a3a
Moved get_integration from Hub to Client
antonpirker Nov 29, 2023
4869365
Moved add_breadcrumb from Hub to Scope
antonpirker Nov 29, 2023
e5f9e9d
Moved session functions from Hub to Scope
antonpirker Nov 29, 2023
a338099
Fixed import
antonpirker Nov 29, 2023
d900a1b
Fixed Python 2.7 syntax
antonpirker Nov 29, 2023
0afb3ab
Merge branch 'master' into antonpirker/refactor-hub
antonpirker Nov 30, 2023
fe77d04
Give the client to the scope function. Want to establish a pattern.
antonpirker Dec 1, 2023
4ba7dce
Merge branch 'antonpirker/refactor-hub' of github.com:getsentry/sentr…
antonpirker Dec 1, 2023
b15613a
Moved capture_* functions from Hub to Client
antonpirker Dec 1, 2023
8331bd0
Renamed scope_args to scope_kwargs
antonpirker Dec 1, 2023
ce1759f
oops
antonpirker Dec 1, 2023
9a08b6e
preserve old behavior when called from client directly (not from hub)
antonpirker Dec 1, 2023
f9b8d5a
update test
antonpirker Dec 1, 2023
d233ae5
Merge branch 'master' into antonpirker/refactor-hub-capture
antonpirker Dec 4, 2023
2932adc
Merge branch 'master' into antonpirker/refactor-hub
antonpirker Dec 4, 2023
3a7af73
Merge branch 'antonpirker/refactor-hub' into antonpirker/refactor-hub…
antonpirker Dec 4, 2023
345c419
Merge branch 'master' into antonpirker/refactor-hub-capture
sentrivana Dec 6, 2023
bb3250a
_update_scope belongs into the scope not the client
antonpirker Dec 11, 2023
3a22dd6
Made top_scope separate parameter
antonpirker Dec 11, 2023
c78b1f5
Hub calls capture_* on scope that calls it on client. Later with new …
antonpirker Dec 13, 2023
0901e72
Merge branch 'feat/new-scopes' into antonpirker/refactor-hub-capture
antonpirker Dec 13, 2023
269fd56
Moved everything to scope and only have capture_event in client
antonpirker Dec 13, 2023
0354065
small fix
antonpirker Dec 13, 2023
3d5825e
Updated test
antonpirker Dec 13, 2023
4e78d1f
Fixed test
antonpirker Dec 13, 2023
ba72216
Fixed test
antonpirker Dec 14, 2023
c5a7ae7
Fixed test for old python
antonpirker Dec 14, 2023
bbb93e6
Formatting
antonpirker Dec 14, 2023
12e632d
Passing the client as separate argument and updating api docs.
antonpirker Dec 14, 2023
eb56a12
ApiDocs
antonpirker Dec 14, 2023
074a9ef
Fix
antonpirker Dec 14, 2023
6733114
Remove condition from _merge_scope (also not present in current imple…
antonpirker Dec 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/apidocs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ API Docs
.. autoclass:: sentry_sdk.Client
:members:

.. autoclass:: sentry_sdk.client._Client
:members:

.. autoclass:: sentry_sdk.Transport
:members:

Expand Down
12 changes: 6 additions & 6 deletions sentry_sdk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,31 +82,31 @@ def capture_event(
event, # type: Event
hint=None, # type: Optional[Hint]
scope=None, # type: Optional[Any]
**scope_args # type: Any
**scope_kwargs # type: Any
):
# type: (...) -> Optional[str]
return Hub.current.capture_event(event, hint, scope=scope, **scope_args)
return Hub.current.capture_event(event, hint, scope=scope, **scope_kwargs)


@hubmethod
def capture_message(
message, # type: str
level=None, # type: Optional[str]
scope=None, # type: Optional[Any]
**scope_args # type: Any
**scope_kwargs # type: Any
):
# type: (...) -> Optional[str]
return Hub.current.capture_message(message, level, scope=scope, **scope_args)
return Hub.current.capture_message(message, level, scope=scope, **scope_kwargs)


@hubmethod
def capture_exception(
error=None, # type: Optional[Union[BaseException, ExcInfo]]
scope=None, # type: Optional[Any]
**scope_args # type: Any
**scope_kwargs # type: Any
):
# type: (...) -> Optional[str]
return Hub.current.capture_exception(error, scope=scope, **scope_args)
return Hub.current.capture_exception(error, scope=scope, **scope_kwargs)


@hubmethod
Expand Down
6 changes: 4 additions & 2 deletions sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ class _Client(object):
forwarding them to sentry through the configured transport. It takes
the client options as keyword arguments and optionally the DSN as first
argument.

Alias of :py:class:`Client`. (Was created for better intelisense support)
"""

def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -560,8 +562,8 @@ def capture_event(

:param hint: Contains metadata about the event that can be read from `before_send`, such as the original exception object or a HTTP request object.

:param scope: An optional scope to use for determining whether this event
should be captured.
:param scope: An optional :py:class:`sentry_sdk.Scope` to apply to events.
The `scope` and `scope_kwargs` parameters are mutually exclusive.

:returns: An event ID. May be `None` if there is no DSN set or of if the SDK decided to discard the event for other reasons. In such situations setting `debug=True` on `init()` may help.
"""
Expand Down
120 changes: 63 additions & 57 deletions sentry_sdk/hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
)

from sentry_sdk.utils import (
exc_info_from_error,
event_from_exception,
logger,
ContextVar,
)
Expand Down Expand Up @@ -65,24 +63,6 @@ def overload(x):
_local = ContextVar("sentry_current_hub")


def _update_scope(base, scope_change, scope_kwargs):
# type: (Scope, Optional[Any], Dict[str, Any]) -> Scope
if scope_change and scope_kwargs:
raise TypeError("cannot provide scope and kwargs")
if scope_change is not None:
final_scope = copy.copy(base)
if callable(scope_change):
scope_change(final_scope)
else:
final_scope.update_from_scope(scope_change)
elif scope_kwargs:
final_scope = copy.copy(base)
final_scope.update_from_kwargs(**scope_kwargs)
else:
final_scope = base
return final_scope


def _should_send_default_pii():
# type: () -> bool
client = Hub.current.client
Expand Down Expand Up @@ -322,76 +302,100 @@ def bind_client(
top = self._stack[-1]
self._stack[-1] = (new, top[1])

def capture_event(self, event, hint=None, scope=None, **scope_args):
def capture_event(self, event, hint=None, scope=None, **scope_kwargs):
# type: (Event, Optional[Hint], Optional[Scope], Any) -> Optional[str]
"""
Captures an event.

Alias of :py:meth:`sentry_sdk.Client.capture_event`.
Alias of :py:meth:`sentry_sdk.Scope.capture_event`.

:param event: A ready-made event that can be directly sent to Sentry.

:param scope_args: For supported `**scope_args` see
:py:meth:`sentry_sdk.Scope.update_from_kwargs`.
:param hint: Contains metadata about the event that can be read from `before_send`, such as the original exception object or a HTTP request object.

:param scope: An optional :py:class:`sentry_sdk.Scope` to apply to events.
The `scope` and `scope_kwargs` parameters are mutually exclusive.

:param scope_kwargs: Optional data to apply to event.
For supported `**scope_kwargs` see :py:meth:`sentry_sdk.Scope.update_from_kwargs`.
The `scope` and `scope_kwargs` parameters are mutually exclusive.
"""
client, top_scope = self._stack[-1]
scope = _update_scope(top_scope, scope, scope_args)
if client is not None:
is_transaction = event.get("type") == "transaction"
rv = client.capture_event(event, hint, scope)
if rv is not None and not is_transaction:
self._last_event_id = rv
return rv
return None
if client is None:
return None

last_event_id = top_scope.capture_event(
event, hint, client=client, scope=scope, **scope_kwargs
)

def capture_message(self, message, level=None, scope=None, **scope_args):
is_transaction = event.get("type") == "transaction"
if last_event_id is not None and not is_transaction:
self._last_event_id = last_event_id

return last_event_id

def capture_message(self, message, level=None, scope=None, **scope_kwargs):
# type: (str, Optional[str], Optional[Scope], Any) -> Optional[str]
"""
Captures a message.

:param message: The string to send as the message.
Alias of :py:meth:`sentry_sdk.Scope.capture_message`.

:param message: The string to send as the message to Sentry.

:param level: If no level is provided, the default level is `info`.

:param scope: An optional :py:class:`sentry_sdk.Scope` to use.
:param scope: An optional :py:class:`sentry_sdk.Scope` to apply to events.
The `scope` and `scope_kwargs` parameters are mutually exclusive.

:param scope_args: For supported `**scope_args` see
:py:meth:`sentry_sdk.Scope.update_from_kwargs`.
:param scope_kwargs: Optional data to apply to event.
For supported `**scope_kwargs` see :py:meth:`sentry_sdk.Scope.update_from_kwargs`.
The `scope` and `scope_kwargs` parameters are mutually exclusive.

:returns: An `event_id` if the SDK decided to send the event (see :py:meth:`sentry_sdk.Client.capture_event`).
"""
if self.client is None:
client, top_scope = self._stack[-1]
if client is None:
return None
if level is None:
level = "info"
return self.capture_event(
{"message": message, "level": level}, scope=scope, **scope_args

last_event_id = top_scope.capture_message(
message, level=level, client=client, scope=scope, **scope_kwargs
)

def capture_exception(self, error=None, scope=None, **scope_args):
if last_event_id is not None:
self._last_event_id = last_event_id

return last_event_id

def capture_exception(self, error=None, scope=None, **scope_kwargs):
# type: (Optional[Union[BaseException, ExcInfo]], Optional[Scope], Any) -> Optional[str]
"""Captures an exception.

:param error: An exception to catch. If `None`, `sys.exc_info()` will be used.
Alias of :py:meth:`sentry_sdk.Scope.capture_exception`.

:param error: An exception to capture. If `None`, `sys.exc_info()` will be used.

:param scope: An optional :py:class:`sentry_sdk.Scope` to apply to events.
The `scope` and `scope_kwargs` parameters are mutually exclusive.

:param scope_args: For supported `**scope_args` see
:py:meth:`sentry_sdk.Scope.update_from_kwargs`.
:param scope_kwargs: Optional data to apply to event.
For supported `**scope_kwargs` see :py:meth:`sentry_sdk.Scope.update_from_kwargs`.
The `scope` and `scope_kwargs` parameters are mutually exclusive.

:returns: An `event_id` if the SDK decided to send the event (see :py:meth:`sentry_sdk.Client.capture_event`).
"""
client = self.client
client, top_scope = self._stack[-1]
if client is None:
return None
if error is not None:
exc_info = exc_info_from_error(error)
else:
exc_info = sys.exc_info()

event, hint = event_from_exception(exc_info, client_options=client.options)
try:
return self.capture_event(event, hint=hint, scope=scope, **scope_args)
except Exception:
self._capture_internal_exception(sys.exc_info())
last_event_id = top_scope.capture_exception(
error, client=client, scope=scope, **scope_kwargs
)

return None
if last_event_id is not None:
self._last_event_id = last_event_id

return last_event_id

def _capture_internal_exception(
self, exc_info # type: Any
Expand All @@ -401,6 +405,8 @@ def _capture_internal_exception(
Capture an exception that is likely caused by a bug in the SDK
itself.

Duplicated in :py:meth:`sentry_sdk.Client._capture_internal_exception`.

These exceptions do not end up in Sentry and are just logged instead.
"""
logger.error("Internal error in sentry_sdk", exc_info=exc_info)
Expand Down
Loading
Loading