Skip to content

Commit

Permalink
API v2 fixes (#6931)
Browse files Browse the repository at this point in the history
* Better stack trace for API v2 on Python 2

* Fix `text/plain` response charset

Before: `2019-07-10 02:12:30 INFO     MAIN :: [f1dc11a] 76703: Unable to find IMDb info in the database: Pokֳ©mon`
After: `2019-07-10 02:13:23 INFO     MAIN :: [f1dc11a] 76703: Unable to find IMDb info in the database: Pokémon`

* Update changelog

* Update base.py

Remove `future` import
  • Loading branch information
sharkykh authored and medariox committed Jul 10, 2019
1 parent d165e4e commit fd5f847
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 6 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
#### Improvements
- Converted the footer to a Vue component ([#4520](https://github.com/pymedusa/Medusa/pull/4520))
- Converted Edit Show to a Vue SFC ([#4486](https://github.com/pymedusa/Medusa/pull/4486)
- Improved API v2 exception reporting on Python 2 ([#6931](https://github.com/pymedusa/Medusa/pull/6931))

#### Fixes
- Fixed hdtorrent provider parse the publishing date with the day first ([#6847](https://github.com/pymedusa/Medusa/pull/6847))
- Fixed release link on Help & Info page ([#6854](https://github.com/pymedusa/Medusa/pull/6854))
- Fixed FreeMobile notifier message encode error ([#6867](https://github.com/pymedusa/Medusa/pull/6867))
- Fixed charset on API v2 responses with plain text content ([#6931](https://github.com/pymedusa/Medusa/pull/6931))

-----

Expand Down
30 changes: 25 additions & 5 deletions medusa/server/api/v2/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import logging
import sys
import traceback
from builtins import object
from collections import OrderedDict
from concurrent.futures import ThreadPoolExecutor
from datetime import date, datetime
Expand All @@ -23,8 +22,9 @@
from medusa import app
from medusa.logger.adapters.style import BraceAdapter

from six import ensure_text, iteritems, string_types, text_type, viewitems
from six import PY2, ensure_text, iteritems, string_types, text_type, viewitems

from tornado.concurrent import Future as TornadoFuture
from tornado.gen import coroutine
from tornado.httputil import url_concat
from tornado.ioloop import IOLoop
Expand Down Expand Up @@ -60,8 +60,28 @@ def async_call(self, *args, **kwargs):
return

# Authentication check passed, run the method in a thread
prepared = partial(method, *args, **kwargs)
content = yield IOLoop.current().run_in_executor(executor, prepared)
if PY2:
# On Python 2, the original exception stack trace is not passed from the executor.
# This is a workaround based on https://stackoverflow.com/a/27413025/7597273
tornado_future = TornadoFuture()

def wrapper():
try:
result = method(*args, **kwargs)
except: # noqa: E722 [do not use bare 'except']
tornado_future.set_exc_info(sys.exc_info())
else:
tornado_future.set_result(result)

# `executor.submit()` returns a `concurrent.futures.Future`; wait for it to finish, but ignore the result
yield executor.submit(wrapper)
# When this future is yielded, any stored exceptions are raised (with the correct stack trace).
content = yield tornado_future
else:
# On Python 3+, exceptions contain their original stack trace.
prepared = partial(method, *args, **kwargs)
content = yield IOLoop.current().run_in_executor(executor, prepared)

self.finish(content)

# This creates a bound method `instance.async_call`,
Expand Down Expand Up @@ -139,7 +159,7 @@ def write_error(self, status_code, *args, **kwargs):
error = exc_info[1].log_message or exc_info[1].reason
response = self.api_response(status=status_code, error=error)
elif app.DEVELOPER and exc_info:
self.set_header('content-type', 'text/plain')
self.set_header('content-type', 'text/plain; charset=UTF-8')
self.set_status(500)
for line in traceback.format_exception(*exc_info):
self.write(line)
Expand Down
2 changes: 1 addition & 1 deletion medusa/server/api/v2/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def data_generator():
return self._paginate(data_generator=data_generator)
else:
text = '\n'.join(data_generator())
return self._ok(stream=text, content_type='text/plain')
return self._ok(stream=text, content_type='text/plain; charset=UTF-8')

def post(self):
"""Create a log line.
Expand Down

0 comments on commit fd5f847

Please sign in to comment.