Tuesday, 2 March 2021

Catching errors being thrown within module

I'm using gevent's WSGIServer's serve_forever() method with my own certificate. Something like this:

http_server = WSGIServer(arguments)
http_server.serve_forever()

Obviously, since the certificate isn't recognised, it throws an error:

Traceback (most recent call last):
  File "src/gevent/greenlet.py", line 854, in gevent._gevent_cgreenlet.Greenlet.run
  File "/usr/local/lib/python3.7/dist-packages/gevent/baseserver.py", line 34, in _handle_and_close_when_done
    return handle(*args_tuple)
  File "/usr/local/lib/python3.7/dist-packages/gevent/server.py", line 233, in wrap_socket_and_handle
    with _closing_socket(self.wrap_socket(client_socket, **self.ssl_args)) as ssl_socket:
  File "/usr/local/lib/python3.7/dist-packages/gevent/_ssl3.py", line 802, in wrap_socket
    ciphers=ciphers)
  File "/usr/local/lib/python3.7/dist-packages/gevent/_ssl3.py", line 312, in __init__
    raise x
  File "/usr/local/lib/python3.7/dist-packages/gevent/_ssl3.py", line 308, in __init__
    self.do_handshake()
  File "/usr/local/lib/python3.7/dist-packages/gevent/_ssl3.py", line 667, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_CERTIFICATE_UNKNOWN] sslv3 alert certificate unknown (_ssl.c:1091)
2021-02-25T07:44:54Z <Greenlet at 0x7f5d8ffe5b90: _handle_and_close_when_done(<bound method StreamServer.wrap_socket_and_handle , <bound method StreamServer.do_close of <WSGIServer, (<gevent._socket3.socket [closed] at 0x7f5d9b91a1d)> failed with SSLError

I tried to pass a file object to the error_log argument:

file_with_errors = open("path/to/file", "+w")
http_server = WSGIServer(arguments, error_log=file_with_errors)
http_server.serve_forever()

and I tried simply catching the error:

http_server = WSGIServer(arguments)
try:
    http_server.serve_forever()
except:
    do_something()

but none of these work, which tells me that the error is being thrown and logged somewhere within the gevent module.

To confirm this, I tried:

import io

def func():
    http_server = WSGIServer(arguments)
    http_server.serve_forever()

try:
    _orig_stderr = sys.stderr
    _new_stderr = io.StringIO()
    sys.stderr = _new_stderr
    func()
except:
    file_with_errors = open("path/to/file", "+w")
    _new_stderr.seek(0)
    output = _new_stderr.read()
    file_with_errors.write(output)
    sys.stderr = _orig_stderr
    file_with_errors.close()

and sent a KeyboardInterrupt, which worked. The errors were logged in the file.

Is there any way for me to catch and redirect the error traceback?



from Catching errors being thrown within module

No comments:

Post a Comment