error.py 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. from django.utils.encoding import force_str
  2. from sentry.culprit import generate_culprit
  3. from sentry.utils.safe import truncatechars, get_path, trim
  4. from sentry.stacktraces.processing import get_crash_frame_from_event_data
  5. from sentry.stacktraces.functions import get_function_name_for_frame
  6. from .base import BaseEvent
  7. def get_crash_location(data):
  8. frame = get_crash_frame_from_event_data(
  9. data,
  10. frame_filter=lambda x: x.get("function")
  11. not in (None, "<redacted>", "<unknown>"),
  12. )
  13. if frame is not None:
  14. func = get_function_name_for_frame(frame, data.get("platform"))
  15. return frame.get("filename") or frame.get("abs_path"), func
  16. class ErrorEvent(BaseEvent):
  17. key = "error"
  18. def get_metadata(self, data):
  19. # Check for undocumented interface where exception has no values. Go SDK does this.
  20. # https://docs.sentry.io/development/sdk-dev/event-payloads/exception/
  21. # exception can be an list instead of a dictionary
  22. if isinstance(data.get("exception"), list):
  23. if len(data["exception"]) == 0:
  24. return {}
  25. # Force documented interface
  26. data["exception"] = {"values": data["exception"]}
  27. exception = get_path(data, "exception", "values", -1)
  28. if not exception:
  29. return {}
  30. loc = get_crash_location(data)
  31. rv = {"value": trim(get_path(exception, "value", default=""), 1024)}
  32. # If the exception mechanism indicates a synthetic exception we do not
  33. # want to record the type and value into the metadata.
  34. if not get_path(exception, "mechanism", "synthetic"):
  35. rv["type"] = trim(get_path(exception, "type", default="Error"), 128)
  36. # Attach crash location if available
  37. if loc is not None:
  38. fn, func = loc
  39. if fn:
  40. rv["filename"] = fn
  41. if func:
  42. rv["function"] = func
  43. return rv
  44. def get_title(self, metadata):
  45. ty = metadata.get("type")
  46. if ty is None:
  47. return metadata.get("function") or "<unknown>"
  48. if not metadata.get("value"):
  49. return ty
  50. try:
  51. return "{}: {}".format(ty, truncatechars(metadata["value"].splitlines()[0]))
  52. except AttributeError:
  53. # GlitchTip modification
  54. # Exception value is specified as a string, sometimes it isn't. This is a fallback.
  55. return "{}: {}".format(ty, str(metadata["value"]))
  56. def get_location(self, data):
  57. return force_str(
  58. data.get("culprit")
  59. or data.get("transaction")
  60. or generate_culprit(data)
  61. or ""
  62. )