mirror of https://github.com/docker/compose.git
json_splitter: Don't break when buffer contains leading whitespace.
Add error logging with detailed output for decode errors Signed-off-by: Joffrey F <joffrey@docker.com>
This commit is contained in:
parent
dec2c83014
commit
6f4be1cffc
|
@ -5,11 +5,13 @@ import codecs
|
|||
import hashlib
|
||||
import json
|
||||
import json.decoder
|
||||
import logging
|
||||
|
||||
import six
|
||||
|
||||
|
||||
json_decoder = json.JSONDecoder()
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def get_output_stream(stream):
|
||||
|
@ -60,13 +62,21 @@ def split_buffer(stream, splitter=None, decoder=lambda a: a):
|
|||
yield item
|
||||
|
||||
if buffered:
|
||||
yield decoder(buffered)
|
||||
try:
|
||||
yield decoder(buffered)
|
||||
except ValueError:
|
||||
log.error(
|
||||
'Compose tried parsing the following chunk as a JSON object, '
|
||||
'but failed:\n%s' % repr(buffered)
|
||||
)
|
||||
raise
|
||||
|
||||
|
||||
def json_splitter(buffer):
|
||||
"""Attempt to parse a json object from a buffer. If there is at least one
|
||||
object, return it and the rest of the buffer, otherwise return None.
|
||||
"""
|
||||
buffer = buffer.strip()
|
||||
try:
|
||||
obj, index = json_decoder.raw_decode(buffer)
|
||||
rest = buffer[json.decoder.WHITESPACE.match(buffer, index).end():]
|
||||
|
|
|
@ -15,6 +15,10 @@ class TestJsonSplitter(object):
|
|||
data = '{"foo": "bar"}\n \n{"next": "obj"}'
|
||||
assert utils.json_splitter(data) == ({'foo': 'bar'}, '{"next": "obj"}')
|
||||
|
||||
def test_json_splitter_leading_whitespace(self):
|
||||
data = '\n \r{"foo": "bar"}\n\n {"next": "obj"}'
|
||||
assert utils.json_splitter(data) == ({'foo': 'bar'}, '{"next": "obj"}')
|
||||
|
||||
|
||||
class TestStreamAsText(object):
|
||||
|
||||
|
@ -43,3 +47,16 @@ class TestJsonStream(object):
|
|||
[1, 2, 3],
|
||||
[],
|
||||
]
|
||||
|
||||
def test_with_leading_whitespace(self):
|
||||
stream = [
|
||||
'\n \r\n {"one": "two"}{"x": 1}',
|
||||
' {"three": "four"}\t\t{"x": 2}'
|
||||
]
|
||||
output = list(utils.json_stream(stream))
|
||||
assert output == [
|
||||
{'one': 'two'},
|
||||
{'x': 1},
|
||||
{'three': 'four'},
|
||||
{'x': 2}
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue