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

API v2 fixes #6931

Merged
merged 4 commits into from
Jul 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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