api/serializers: Add Exception type encoder
I stumbled across that error while working on the Web API POC based on OpenAPI
due to uffizi.internal.softwareheritage.org
host currently not available.
INFO:werkzeug:127.0.0.1 - - [18/Nov/2020 17:33:25] "POST /content/data HTTP/1.1" 500 -
Traceback (most recent call last):
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/connection.py", line 160, in _new_conn
(self._dns_host, self.port), self.timeout, **extra_kw
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/util/connection.py", line 84, in create_connection
raise err
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/util/connection.py", line 74, in create_connection
sock.connect(sa)
OSError: [Errno 113] No route to host
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/connectionpool.py", line 677, in urlopen
chunked=chunked,
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/connectionpool.py", line 392, in _make_request
conn.request(method, url, **httplib_request_kw)
File "/usr/lib/python3.7/http/client.py", line 1244, in request
self._send_request(method, url, body, headers, encode_chunked)
File "/usr/lib/python3.7/http/client.py", line 1290, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File "/usr/lib/python3.7/http/client.py", line 1239, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File "/usr/lib/python3.7/http/client.py", line 1026, in _send_output
self.send(msg)
File "/usr/lib/python3.7/http/client.py", line 966, in send
self.connect()
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/connection.py", line 187, in connect
conn = self._new_conn()
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/connection.py", line 172, in _new_conn
self, "Failed to establish a new connection: %s" % e
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPConnection object at 0x7fcf9a993ba8>: Failed to establish a new connection: [Errno 113] No route to host
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/requests/adapters.py", line 449, in send
timeout=timeout
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/connectionpool.py", line 767, in urlopen
**response_kw
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/connectionpool.py", line 767, in urlopen
**response_kw
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/connectionpool.py", line 767, in urlopen
**response_kw
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/connectionpool.py", line 727, in urlopen
method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2]
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/urllib3/util/retry.py", line 439, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='uffizi.internal.softwareheritage.org', port=5003): Max retries exceeded with url: /content/get (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fcf9a993ba8>: Failed to establish a new connection: [Errno 113] No route to host'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/anlambert/swh/swh-environment/swh-core/swh/core/api/__init__.py", line 254, in raw_verb
return getattr(self.session, verb)(self._url(endpoint), **opts)
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/requests/sessions.py", line 578, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/requests/sessions.py", line 530, in request
resp = self.send(prep, **send_kwargs)
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/requests/sessions.py", line 643, in send
r = adapter.send(request, **kwargs)
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/requests/adapters.py", line 516, in send
raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='uffizi.internal.softwareheritage.org', port=5003): Max retries exceeded with url: /content/get (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fcf9a993ba8>: Failed to establish a new connection: [Errno 113] No route to host'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/flask/app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/flask/app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "<decorator-gen-10>", line 2, in content_get_data
File "/home/anlambert/swh/swh-environment/swh-core/swh/core/api/negotiation.py", line 147, in _negotiate
return f.negotiator(*args, **kwargs)
File "/home/anlambert/swh/swh-environment/swh-core/swh/core/api/negotiation.py", line 81, in __call__
result = self.func(*args, **kwargs)
File "/home/anlambert/swh/swh-environment/swh-core/swh/core/api/__init__.py", line 456, in _f
return obj_meth(**kw)
File "/home/anlambert/swh/swh-environment/swh-storage/swh/storage/metrics.py", line 24, in d
return f(*a, **kw)
File "/home/anlambert/swh/swh-environment/swh-storage/swh/storage/postgresql/storage.py", line 274, in content_get_data
return self.objstorage.content_get(content)
File "/home/anlambert/swh/swh-environment/swh-storage/swh/storage/objstorage.py", line 41, in content_get
data = self.objstorage.get(obj_id)
File "/home/anlambert/swh/swh-environment/swh-objstorage/swh/objstorage/multiplexer/multiplexer_objstorage.py", line 278, in get
return storage.get(obj_id)
File "/home/anlambert/swh/swh-environment/swh-objstorage/swh/objstorage/multiplexer/multiplexer_objstorage.py", line 105, in call
return self.get_result_from_mailbox(mailbox)
File "/home/anlambert/swh/swh-environment/swh-objstorage/swh/objstorage/multiplexer/multiplexer_objstorage.py", line 83, in get_result_from_mailbox
raise result["result"] from None
File "/home/anlambert/swh/swh-environment/swh-objstorage/swh/objstorage/multiplexer/multiplexer_objstorage.py", line 28, in run
ret = getattr(self.storage, command)(*args, **kwargs)
File "/home/anlambert/swh/swh-environment/swh-objstorage/swh/objstorage/api/client.py", line 54, in get
return self._proxy.post("content/get", {"obj_id": obj_id})
File "/home/anlambert/swh/swh-environment/swh-core/swh/core/api/__init__.py", line 272, in post
**opts,
File "/home/anlambert/swh/swh-environment/swh-core/swh/core/api/__init__.py", line 256, in raw_verb
raise self.api_exception(e)
swh.objstorage.exc.ObjStorageAPIError: An unexpected error occurred in the api backend: HTTPConnectionPool(host='uffizi.internal.softwareheritage.org', port=5003): Max retries exceeded with url: /content/get (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fcf9a993ba8>: Failed to establish a new connection: [Errno 113] No route to host'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/flask/app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/flask/app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/flask/app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/flask/app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/flask/app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/flask/app.py", line 1822, in handle_user_exception
return handler(e)
File "/home/anlambert/swh/swh-environment/swh-storage/swh/storage/api/server.py", line 48, in my_error_handler
return error_handler(exception, encode_data)
File "/home/anlambert/swh/swh-environment/swh-core/swh/core/api/__init__.py", line 399, in error_handler
response = encoder(exception_to_dict(exception))
File "/home/anlambert/swh/swh-environment/swh-core/swh/core/api/__init__.py", line 375, in encode_data_server
encoded_data = ENCODERS[content_type](data, extra_encoders=extra_type_encoders)
File "/home/anlambert/swh/swh-environment/swh-core/swh/core/api/serializers.py", line 228, in msgpack_dumps
return msgpack.packb(data, use_bin_type=True, default=encode_types)
File "/home/anlambert/.virtualenvs/swh/lib/python3.7/site-packages/msgpack/__init__.py", line 35, in packb
return Packer(**kwargs).pack(o)
File "msgpack/_packer.pyx", line 286, in msgpack._cmsgpack.Packer.pack
File "msgpack/_packer.pyx", line 292, in msgpack._cmsgpack.Packer.pack
File "msgpack/_packer.pyx", line 289, in msgpack._cmsgpack.Packer.pack
File "msgpack/_packer.pyx", line 225, in msgpack._cmsgpack.Packer._pack
File "msgpack/_packer.pyx", line 225, in msgpack._cmsgpack.Packer._pack
File "msgpack/_packer.pyx", line 258, in msgpack._cmsgpack.Packer._pack
File "msgpack/_packer.pyx", line 283, in msgpack._cmsgpack.Packer._pack
TypeError: can not serialize 'ConnectionError' object
A RemoteException
could not be properly serialized due to the corner case
that the wrapped expection has been constructed with another exception
argument (here ObjStorageAPIError(ConnectionError())
).
So handle that special case by adding a dedicated encoder to avoid remote exception serialization error.
Migrated from D4515 (view on Phabricator)