Repository: getsentry/sentry-python

Issue:
Wrong display of cyrillic characters in sentry
In **Exception** section in Sentry cyrillic characters do not display correctly:
![screen shot 2018-09-25 at 13 49 01](https://user-images.githubusercontent.com/11457111/46010144-52360980-c0ca-11e8-95d1-5f8a901a0e31.png)



Discussion:
Hi Maxim, could you give me a piece of code that generates such an event? Generally UTF-8 works for me.
```python
from sentry_sdk import capture_exception
from another_file import AD

def foo():
    ad = AD()

    input = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
    
    for line in input:
        try:
            message = json.loads(line)
        except json.decoder.JSONDecodeError as err:
            continue
        try:
            ad.process_message(message)
        except Exception as exc:
            capture_exception(exc)

# method from imported class
def process_message(self, message: Dict) -> None:
    try:
        for field, value in self.message_filters.items():
            if message.get(field) != value:
                return

        record = message.get('record')  #  this variable(and message variable) do not display correctly
        if not record:
            return
        self.process_record(record)
    except Exception as exc:  # noqa: pylint=broad-except
        logging.error(f'============ERROR START============\n'
                          f'{record}\n'
                          f'============ERROR STOP============')
        raise Exception()
```

In **BREADCRUMBS** cyrillic characters display correctly:
![screen shot 2018-09-25 at 14 24 44](https://user-images.githubusercontent.com/11457111/46011603-09348400-c0cf-11e8-8d8c-d1bce1c7c938.png)


Resolving patch:
diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py
--- a/sentry_sdk/utils.py
+++ b/sentry_sdk/utils.py
@@ -260,11 +260,25 @@ def safe_repr(value):
         rv = repr(value)
         if isinstance(rv, bytes):
             rv = rv.decode("utf-8", "replace")
+
+        # At this point `rv` contains a bunch of literal escape codes, like
+        # this (exaggerated example):
+        #
+        # u"\\x2f"
+        #
+        # But we want to show this string as:
+        #
+        # u"/"
         try:
-            return rv.encode("utf-8").decode("unicode-escape")
+            # unicode-escape does this job, but can only decode latin1. So we
+            # attempt to encode in latin1.
+            return rv.encode("latin1").decode("unicode-escape")
         except Exception:
+            # Since usually strings aren't latin1 this can break. In those
+            # cases we just give up.
             return rv
     except Exception:
+        # If e.g. the call to `repr` already fails
         return u"<broken repr>"
 
 


Test patch:
diff --git a/tests/test_utils.py b/tests/test_utils.py
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -1,7 +1,8 @@
+# coding: utf-8
 import sys
 import os
 
-from hypothesis import given, assume
+from hypothesis import given
 import hypothesis.strategies as st
 
 from sentry_sdk.utils import safe_repr, exceptions_from_error_tuple
@@ -17,15 +18,8 @@ def test_safe_repr_never_broken_for_strings(x):
     assert u"broken repr" not in r
 
 
-@given(x=any_string)
-def test_safe_repr_never_leaves_escapes_in(x):
-    if isinstance(x, bytes):
-        assume(b"\\u" not in x and b"\\x" not in x)
-    else:
-        assume(u"\\u" not in x and u"\\x" not in x)
-    r = safe_repr(x)
-    assert isinstance(r, text_type)
-    assert u"\\u" not in r and u"\\x" not in r
+def test_safe_repr_regressions():
+    assert u"лошадь" in safe_repr(u"лошадь")
 
 
 def test_abs_path():