Skip to content

Commit

Permalink
Fix encoding error (#17)
Browse files Browse the repository at this point in the history
Fix encoding error when reading standard error stream in certain systems
  • Loading branch information
jonmmease authored Jul 23, 2020
1 parent 71f5b6b commit 6069cf6
Showing 1 changed file with 30 additions and 6 deletions.
36 changes: 30 additions & 6 deletions repos/kaleido/py/kaleido/scopes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import io
import os
import sys
import locale

try:
from json import JSONDecodeError
Expand Down Expand Up @@ -34,7 +35,7 @@ def __init__(self, disable_gpu=True):
self._disable_gpu = disable_gpu

# Internal Properties
self._std_error = io.StringIO()
self._std_error = io.BytesIO()
self._std_error_thread = None
self._proc = None
self._proc_lock = Lock()
Expand Down Expand Up @@ -71,7 +72,7 @@ def _collect_standard_error(self):
"""
while True:
if self._proc is not None:
val = self._proc.stderr.readline().decode('utf-8')
val = self._proc.stderr.readline()
self._std_error.write(val)

def _ensure_kaleido(self):
Expand All @@ -88,7 +89,7 @@ def _ensure_kaleido(self):
self._proc.wait()

# Reset _std_error buffer
self._std_error = io.StringIO()
self._std_error = io.BytesIO()

# Launch kaleido subprocess
# Note: shell=True seems to be needed on Windows to handle executable path with
Expand All @@ -114,7 +115,7 @@ def _ensure_kaleido(self):
if not startup_response_string:
message = (
"Failed to start Kaleido subprocess. Error stream:\n\n" +
self._std_error.getvalue()
self._get_decoded_std_error()
)
raise ValueError(message)
else:
Expand All @@ -123,6 +124,29 @@ def _ensure_kaleido(self):
self._proc.wait()
raise ValueError(startup_response.get("message", "Failed to start Kaleido subprocess"))

def _get_decoded_std_error(self):
"""
Attempt to decode standard error bytes stream to a string
"""
std_err_str = None
try:
encoding = sys.stderr.encoding
std_err_str = self._std_error.getvalue().decode(encoding)
except Exception:
pass

if std_err_str is None:
try:
encoding = locale.getpreferredencoding(False)
std_err_str = self._std_error.getvalue().decode(encoding)
except Exception:
pass

if std_err_str is None:
std_err_str = "Failed to decode Chromium's standard error stream"

return std_err_str

def _shutdown_kaleido(self):
"""
Shut down the kaleido subprocess, if any, and self the _proc property to None
Expand Down Expand Up @@ -185,7 +209,7 @@ def _perform_transform(self, data, **kwargs):
# sure we're reading the response to our request
with self._proc_lock:
# Reset _std_error buffer
self._std_error = io.StringIO()
self._std_error = io.BytesIO()

# Write and flush spec
self._proc.stdin.write(export_spec)
Expand All @@ -197,7 +221,7 @@ def _perform_transform(self, data, **kwargs):
if not response_string:
message = (
"Transform failed. Error stream:\n\n" +
self._std_error.getvalue()
self._get_decoded_std_error()
)
raise ValueError(message)
try:
Expand Down

0 comments on commit 6069cf6

Please sign in to comment.