Repository: pallets/werkzeug

Issue:
WSGIRequestHandler.handle() shouldn't silently discard SSL errors
This is arguably a feature request, not a bug:  It would be great if WSGIRequestHandler.handle() did not silently discard SSL errors.  I have a Flask application that uses client certificates for authentication, and was attempting to run it in debug mode with run_simple.  It would consistently fail after the first request, and no amount of logging would reveal anything, until I went into serving.py, and commented out these lines:

```
            if self.server.ssl_context is None or not is_ssl_error():
                raise
```

That finally allowed me to see that PyOpenSSL was in fact throwing an error (because the session id context is not initialized by default, and I was doing renegotiation), but it was really frustrating.

I am not including a patch, because I'm not sure the best way to implement this.  I could see using the logging module, or setting an environment variable, or something.  WSGIRequestHandler doesn't have an **init** and adding one to support one option seems like overkill, but is a possibility too, I guess.  I'm happy to write the patch and submit a pull request if there's any sort of consensus on the best way to implement it.



Discussion:
From IRC:

```
[21:43:29] <mitsuhiko> +1 on that issue you linked
[21:43:38] <mitsuhiko> i'm trying to find out why it catches them but i have no good reason
[21:44:12] <untitaker> i thought it's probably for errors when the connection is dropped
[21:44:24] <untitaker> but in any case that seems not worth it
[21:44:56] <untitaker> not even the non-SSL code catches all errors, i still get some when interrupting the connection
(broken pipe)
```

Great, thanks!

Regarding the original reasoning, I wouldn't be surprised if some browsers (older IE?) did something wrong with SSL, which caused pyopenssl to maybe raise an error, but I don't have a good test environment for that at the moment.

I don't think it matters. I think an important thing though is that the server stays in a state where it is able to handle subsequent requests. Whether it prints a traceback to stdout because of connection issues is just an annoyance.

@jdreed Are you interested in writing a patch?

Sure, I'll try and find some time over the next week or two and will submit a pull request when I have something.

Not a pull request yet, because I want to test one or two more things, but any objection to a fix of this style:
https://github.com/jdreed/werkzeug/compare/fix_625

Looks fine, please use a simple `raise` to preserve the traceback.


Resolving patch:
diff --git a/src/werkzeug/serving.py b/src/werkzeug/serving.py
--- a/src/werkzeug/serving.py
+++ b/src/werkzeug/serving.py
@@ -329,7 +329,9 @@ def handle(self) -> None:
         except (ConnectionError, socket.timeout) as e:
             self.connection_dropped(e)
         except Exception as e:
-            if self.server.ssl_context is None or not is_ssl_error(e):
+            if self.server.ssl_context is not None and is_ssl_error(e):
+                self.log_error("SSL error occurred: %s", e)
+            else:
                 raise
         if self.server.shutdown_signal:
             self.initiate_shutdown()


Test patch: