mirror of
https://github.com/platformio/platformio-core.git
synced 2025-07-29 17:47:14 +02:00
Fixed an issue with PIO Home's "No JSON object could be decoded" // Resolve #2823
This commit is contained in:
@ -15,6 +15,7 @@ PlatformIO 4.0
|
||||
* Renamed "enable_ssl" setting to `strict_ssl <http://docs.platformio.org/page/userguide/cmd_settings.html#strict-ssl>`__
|
||||
* Fixed an issue with incorrect escaping of Windows slashes when using `PIO Unified Debugger <http://docs.platformio.org/page/plus/debugging.html>`__ and "piped" openOCD
|
||||
* Fixed an issue when "debug", "home", "run", and "test" commands were not shown in "platformio --help" CLI
|
||||
* Fixed an issue with PIO Home's "No JSON object could be decoded" (`issue #2823 <https://github.com/platformio/platformio-core/issues/2823>`_)
|
||||
|
||||
4.0.0 (2019-07-10)
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
@ -21,6 +21,7 @@ from io import BytesIO, StringIO
|
||||
|
||||
import click
|
||||
import jsonrpc # pylint: disable=import-error
|
||||
from twisted.internet import defer # pylint: disable=import-error
|
||||
from twisted.internet import threads # pylint: disable=import-error
|
||||
from twisted.internet import utils # pylint: disable=import-error
|
||||
|
||||
@ -68,6 +69,10 @@ class MultiThreadingStdStream(object):
|
||||
|
||||
class PIOCoreRPC(object):
|
||||
|
||||
@staticmethod
|
||||
def version():
|
||||
return __version__
|
||||
|
||||
@staticmethod
|
||||
def setup_multithreading_std_streams():
|
||||
if isinstance(sys.stdout, MultiThreadingStdStream):
|
||||
@ -79,41 +84,67 @@ class PIOCoreRPC(object):
|
||||
|
||||
@staticmethod
|
||||
def call(args, options=None):
|
||||
PIOCoreRPC.setup_multithreading_std_streams()
|
||||
cwd = (options or {}).get("cwd") or os.getcwd()
|
||||
return defer.maybeDeferred(PIOCoreRPC._call_generator, args, options)
|
||||
|
||||
@staticmethod
|
||||
@defer.inlineCallbacks
|
||||
def _call_generator(args, options=None):
|
||||
for i, arg in enumerate(args):
|
||||
if isinstance(arg, string_types):
|
||||
args[i] = arg.encode(get_filesystem_encoding()) if PY2 else arg
|
||||
else:
|
||||
args[i] = str(arg)
|
||||
|
||||
def _call_inline():
|
||||
to_json = "--json-output" in args
|
||||
|
||||
try:
|
||||
if args and args[0] in ("account", "remote"):
|
||||
result = yield PIOCoreRPC._call_subprocess(args, options)
|
||||
defer.returnValue(PIOCoreRPC._process_result(result, to_json))
|
||||
else:
|
||||
result = yield PIOCoreRPC._call_inline(args, options)
|
||||
try:
|
||||
defer.returnValue(
|
||||
PIOCoreRPC._process_result(result, to_json))
|
||||
except ValueError:
|
||||
# fall-back to subprocess method
|
||||
result = yield PIOCoreRPC._call_subprocess(args, options)
|
||||
defer.returnValue(
|
||||
PIOCoreRPC._process_result(result, to_json))
|
||||
except Exception as e: # pylint: disable=bare-except
|
||||
raise jsonrpc.exceptions.JSONRPCDispatchException(
|
||||
code=4003, message="PIO Core Call Error", data=str(e))
|
||||
|
||||
@staticmethod
|
||||
def _call_inline(args, options):
|
||||
PIOCoreRPC.setup_multithreading_std_streams()
|
||||
cwd = (options or {}).get("cwd") or os.getcwd()
|
||||
|
||||
def _thread_task():
|
||||
with fs.cd(cwd):
|
||||
exit_code = __main__.main(["-c"] + args)
|
||||
return (PIOCoreRPC.thread_stdout.get_value_and_reset(),
|
||||
PIOCoreRPC.thread_stderr.get_value_and_reset(), exit_code)
|
||||
|
||||
if args and args[0] in ("account", "remote"):
|
||||
d = utils.getProcessOutputAndValue(
|
||||
helpers.get_core_fullpath(),
|
||||
args,
|
||||
path=cwd,
|
||||
env={k: v
|
||||
for k, v in os.environ.items() if "%" not in k})
|
||||
else:
|
||||
d = threads.deferToThread(_call_inline)
|
||||
|
||||
d.addCallback(PIOCoreRPC._call_callback, "--json-output" in args)
|
||||
d.addErrback(PIOCoreRPC._call_errback)
|
||||
return d
|
||||
return threads.deferToThread(_thread_task)
|
||||
|
||||
@staticmethod
|
||||
def _call_callback(result, json_output=False):
|
||||
def _call_subprocess(args, options):
|
||||
cwd = (options or {}).get("cwd") or os.getcwd()
|
||||
return utils.getProcessOutputAndValue(
|
||||
helpers.get_core_fullpath(),
|
||||
args,
|
||||
path=cwd,
|
||||
env={k: v
|
||||
for k, v in os.environ.items() if "%" not in k})
|
||||
|
||||
@staticmethod
|
||||
def _process_result(result, to_json=False):
|
||||
out, err, code = result
|
||||
text = ("%s\n\n%s" % (out, err)).strip()
|
||||
if code != 0:
|
||||
raise Exception(text)
|
||||
if not json_output:
|
||||
if not to_json:
|
||||
return text
|
||||
try:
|
||||
return json.loads(out)
|
||||
@ -129,14 +160,3 @@ class PIOCoreRPC(object):
|
||||
except ValueError:
|
||||
pass
|
||||
raise e
|
||||
|
||||
@staticmethod
|
||||
def _call_errback(failure):
|
||||
raise jsonrpc.exceptions.JSONRPCDispatchException(
|
||||
code=4003,
|
||||
message="PIO Core Call Error",
|
||||
data=failure.getErrorMessage())
|
||||
|
||||
@staticmethod
|
||||
def version():
|
||||
return __version__
|
||||
|
Reference in New Issue
Block a user