getsentry / getsentry/sentry-python

Exceptions are formatted incorrectly (or even fail) when `message` or `detail` attribute presents

Đang mở
#5,050 4 bình luận 1 reaction 1 người được giao Được @alexander-alderman-webb nhận Xem trên GitHub
Bug Errors Python
Ngôn ngữ chính
Python
Star
2.2k
Fork
669
Merge trung bình
1 ngày 1 giờ
Pull request đã merge (30 ngày)
213

Mô tả

### How do you use Sentry?

Self-hosted/on-premise

### Version

2.43.0

### Steps to Reproduce

Some of our exception define properties `message` and `detail`. The formatting of error message for those exceptions is almost always incorrect (doesn't contain important information, not formatted properly) or sometimes even fails. There is a couple of such exceptions in simplified form:

```python
class GRpcError(Exception):
def __init__(self, code: int, message: bytes) -> None:
super().__init__(code, message)
self.code = code
# Original protobuf message to allow its inspection in error handlers.
# Here we use bytes, but it can be `google.protobuf.message.Message`
# instance as well.
self.message = message

def __str__(self) -> str:
return f"code={self.code}"

class ApiError(Exception):
def __init__(self, code: str, detail: dict[str, Any]) -> None:
super().__init__(code, detail)
self.code = code
self.detail = detail

def __str__(self) -> str:
formatted = f"[{self.code}]"
for key, value in self.detail.items():
formatted += f"\n {key}={value}"
return formatted
```

### Expected Result

Here is how they are formatted by Python itself:
```python
grpc_exc = GRpcError(13, b"unreadable protobuf message")

print("".join(traceback.format_exception_only(grpc_exc)).strip())
# GRpcError: code=13

grpc_exc.add_note("additional context note")

print("".join(traceback.format_exception_only(grpc_exc)).strip())
# GRpcError: code=13
# additional context note

api_exc = ApiError("RATE_LIMIT_EXCEEDED", detail={"retry_after": 30})

print("".join(traceback.format_exception_only(api_exc)).strip())
# ApiError: [RATE_LIMIT_EXCEEDED]
# retry_after=30

api_exc.add_note("additional context note")

print("".join(traceback.format_exception_only(api_exc)).strip())
# ApiError: [RATE_LIMIT_EXCEEDED]
# retry_after=30
# additional context note
```

### Actual Result

And the formatting by sentry (`get_error_message` is used internally by `event_from_exception`, here I call it directly):

```python
grpc_exc = GRpcError(13, b"unreadable protobuf message")

print(sentry_sdk.utils.get_error_message(grpc_exc))
# No `code` field, only unreadable field in the result:
# b'unreadable protobuf message'

grpc_exc.add_note("additional context note")

print(sentry_sdk.utils.get_error_message(grpc_exc))
# Fails with the error:
# TypeError: can't concat str to bytes

api_exc = ApiError("RATE_LIMIT_EXCEEDED", detail={"retry_after": 30})

print(sentry_sdk.utils.get_error_message(api_exc))
# No `code` field, `detail` is not formatted:
# {'retry_after': 30}

api_exc.add_note("additional context note")

print(sentry_sdk.utils.get_error_message(api_exc))
# Fails with the error:
# TypeError: unsupported operand type(s) for +=: 'dict' and 'str'
```

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.