correct exception handling / error reporting with Python 3

This commit is contained in:
Sławomir Nizio
2019-12-13 01:20:59 +01:00
parent 4ab520925a
commit 2aa2c69e2b
5 changed files with 44 additions and 29 deletions
+2 -1
View File
@@ -62,7 +62,8 @@ def handle_exception(exc_class, exc_instance, exc_tb):
if exc_class is KeyboardInterrupt:
os._exit(1)
t_back = entropy.tools.get_traceback(tb_obj = exc_tb)
t_back = entropy.tools.get_traceback(
exc_info = (exc_class, exc_instance, exc_tb))
if const_debug_enabled():
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
+8 -10
View File
@@ -20,13 +20,10 @@ import hashlib
import time
import codecs
from entropy.const import const_is_python3, const_debug_write, \
const_dir_writable, const_isfileobj
from entropy.const import const_debug_write, const_dir_writable, \
const_isfileobj
if const_is_python3():
from io import StringIO
else:
from cStringIO import StringIO
from io import BytesIO
from entropy.const import const_get_stringtype, etpConst, const_setup_perms, \
const_convert_to_rawstring, const_convert_to_unicode, const_mkstemp
@@ -1492,10 +1489,11 @@ class ClientWebService(WebService):
file_params = {}
for k, v in error_params.items():
if isinstance(v, const_get_stringtype()):
sio = StringIO()
sio.write(v)
sio.seek(0)
file_params[k] = (k + ".txt", sio)
bio = BytesIO()
v_raw = const_convert_to_rawstring(v)
bio.write(v_raw)
bio.seek(0)
file_params[k] = (k + ".txt", bio)
else:
params[k] = v
self._method_getter("report_error", params,
+21 -12
View File
@@ -21,7 +21,7 @@ import ssl
import socket
from entropy.const import const_is_python3, const_convert_to_rawstring, \
const_get_int, const_mkstemp, const_dir_writable
const_get_int, const_mkstemp, const_dir_writable, const_get_int
if const_is_python3():
import http.client as httplib
@@ -444,7 +444,7 @@ class WebService(object):
def _cast_to_str(value):
if value is None:
return const_convert_to_rawstring("")
elif isinstance(value, (int, float, long)):
elif isinstance(value, const_get_int() + (float,)):
return const_convert_to_rawstring(value)
elif isinstance(value, (list, tuple)):
return repr(value)
@@ -453,20 +453,29 @@ class WebService(object):
tmp_fd, tmp_path = const_mkstemp(prefix="_encode_multipart_form")
tmp_f = os.fdopen(tmp_fd, "ab+")
tmp_f.truncate(0)
crlf = '\r\n'
crlf = const_convert_to_rawstring('\r\n')
dashes = const_convert_to_rawstring("--")
raw_boundary = const_convert_to_rawstring(boundary)
for key, value in params.items():
tmp_f.write("--" + boundary + crlf)
tmp_f.write("Content-Disposition: form-data; name=\"%s\"" % (
key,))
tmp_f.write(dashes + raw_boundary + crlf)
tmp_f.write(
const_convert_to_rawstring(
"Content-Disposition: form-data; name=\"%s\"" % (key,)))
tmp_f.write(crlf + crlf + _cast_to_str(value) + crlf)
for key, (f_name, f_obj) in file_params.items():
tmp_f.write("--" + boundary + crlf)
tmp_f.write(dashes + raw_boundary + crlf)
tmp_f.write(
"Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"" % (
key, f_name,))
const_convert_to_rawstring(
"Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"" % (
key, f_name,)))
tmp_f.write(crlf)
tmp_f.write("Content-Type: application/octet-stream" + crlf)
tmp_f.write("Content-Transfer-Encoding: binary" + crlf + crlf)
tmp_f.write(
const_convert_to_rawstring(
"Content-Type: application/octet-stream") + crlf)
tmp_f.write(
const_convert_to_rawstring(
"Content-Transfer-Encoding: binary") + crlf + crlf)
f_obj.seek(0)
while True:
chunk = f_obj.read(65536)
@@ -475,7 +484,7 @@ class WebService(object):
tmp_f.write(chunk)
tmp_f.write(crlf)
tmp_f.write("--" + boundary + "--" + crlf + crlf)
tmp_f.write(dashes + raw_boundary + dashes + crlf + crlf)
tmp_f.flush()
return tmp_f, tmp_path
+9 -3
View File
@@ -162,22 +162,28 @@ def print_traceback(f = None):
"""
traceback.print_exc(file = f)
def get_traceback(tb_obj = None):
def get_traceback(tb_obj = None, exc_info = None):
"""
Return last available Python traceback.
@return: traceback data
@rtype: string
@keyword tb_obj: Python traceback object
@keyword tb_obj: Python traceback object; ignored when exc_info is provided
@type tb_obj: Python traceback instance
@keyword exc_info: tuple as in sys.exc_info()
@type tb_obj: tuple
"""
if const_is_python3():
from io import StringIO
else:
from cStringIO import StringIO
buf = StringIO()
if tb_obj is not None:
if exc_info is not None:
traceback.print_exception(*exc_info, file = buf)
elif tb_obj is not None:
# legacy way, kept for compatibiilty
if const_is_python3():
# does not print all exception data
traceback.print_tb(tb_obj, file = buf)
else:
traceback.print_last(tb_obj, file = buf)
+4 -3
View File
@@ -70,7 +70,7 @@ from entropy.db.cache import EntropyRepositoryCachePolicies
_NONE_POL = EntropyRepositoryCachePolicies.NONE
EntropyRepositoryCachePolicies.DEFAULT_CACHE_POLICY = _NONE_POL
from entropy.const import etpConst, const_convert_to_rawstring, \
from entropy.const import etpConst, \
initconfig_entropy_constants, const_debug_write, dump_signal, \
const_mkstemp, const_is_python3
from entropy.locks import EntropyResourcesLock, UpdatesNotificationResourceLock
@@ -166,11 +166,12 @@ def uninstall_exception_handler():
sys.excepthook = sys.__excepthook__
def handle_exception(_exc_class, exc_instance, exc_tb):
t_back = entropy.tools.get_traceback(tb_obj = exc_tb)
t_back = entropy.tools.get_traceback(
exc_info = (_exc_class, exc_instance, exc_tb))
# restore original exception handler, to avoid loops
uninstall_exception_handler()
# write exception to log file
write_output(const_convert_to_rawstring(t_back), debug=True)
write_output(t_back, debug=True)
raise exc_instance
install_exception_handler()