Repository: RocketMap/RocketMap

Issue:
Need to better handle flask 'broken pipe' errors
<!--

  ISSUES ARE NOT FOR SUPPORT!!!
  ISSUES ARE NOT FOR SUPPORT!!!
  ISSUES ARE NOT FOR SUPPORT!!!
  ISSUES ARE NOT FOR SUPPORT!!!
  ISSUES ARE NOT FOR SUPPORT!!!
  ISSUES ARE NOT FOR SUPPORT!!!
  ISSUES ARE NOT FOR SUPPORT!!!
  ISSUES ARE NOT FOR SUPPORT!!!

  Join discord (channel: #help) for support at this link: https://discord.gg/rocketmap
  
  Submit feature requests @ http://vote.devkat.org
  
-->

<!--- Provide a general summary of the issue in the Title above -->
## Expected Behavior
<!--- If you're describing a bug, tell us what should happen -->
<!--- If you're suggesting a change/improvement, tell us how it should work -->

Need to trap and cleanly handle the following issue.  It causes endless questions in #help and answer is always that it's a flask error that can be ignored.

```
2017-08-25 23:12:13,250 [     Thread-506835][     runserver][   ERROR] Uncaught exception
Traceback (most recent call last):
  File "runserver.py", line 89, in run
    run_old(*args, **kwargs)
  File "/usr/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib/python2.7/SocketServer.py", line 599, in process_request_thread
    self.handle_error(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 596, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 331, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 654, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 713, in finish
    self.wfile.close()
  File "/usr/lib/python2.7/socket.py", line 283, in close
    self.flush()
  File "/usr/lib/python2.7/socket.py", line 307, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe
```

## Current Behavior
<!--- If describing a bug, tell us what happens instead of the expected behavior -->
<!--- If suggesting a change/improvement, explain the difference from current behavior -->
The error above occurs

## Possible Solution
<!--- Not obligatory, but suggest a fix/reason for the bug, -->
<!--- or ideas how to implement the addition or change -->
Trap this issue and only put a controlled error message in the log

## Steps to Reproduce (for bugs)
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug. Include code to reproduce, if relevant -->
1. Run rocketmap for a while
2. Check logs
3. You likely will see this common error that can be ignored

## Context
<!--- How has this issue affected you? What are you trying to accomplish? -->
<!--- Providing context helps us come up with a solution that is most useful in the real world -->
Expectation is only to have real exceptions showing up in logs.  This is a known one.  If we address the issue and have a clean log entry it causes less headaches because when you look at the console and see an exception you will know it is something that merits investigation.

## Your Environment
<!--- Include as many relevant details about the environment you experienced the bug in -->
* Version used:
* Environment name and version (e.g. Python 2.7):
* Operating System and version (desktop or mobile):
Ubunto 16.04 VPS



Discussion:
👍 As discussed on Discord, I'll take care of this asap.
Updating Flask did resolve a related issue and handles requests better, but the exception still occurs. I'll submit another PR to handle that specific case.
@tomballgithub Could you run #2304 (and approve if it works for you), then get it to log the "Broken pipe" exception details?
`

2017-09-21 11:02:22,679 [         Thread-50][     runserver][CRITICAL] Unhandled patched exception (error): "".
2017-09-21 11:02:22,679 [         Thread-50][     runserver][   ERROR] Uncaught exception
Traceback (most recent call last):
  File "runserver.py", line 89, in run
    run_old(*args, **kwargs)
  File "/usr/lib/python2.7/threading.py", line 754, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib/python2.7/SocketServer.py", line 599, in process_request_thread
    self.handle_error(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 596, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/lib/python2.7/SocketServer.py", line 331, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/lib/python2.7/SocketServer.py", line 654, in __init__
    self.finish()
  File "/usr/lib/python2.7/SocketServer.py", line 713, in finish
    self.wfile.close()
  File "/usr/lib/python2.7/socket.py", line 283, in close
    self.flush()
  File "/usr/lib/python2.7/socket.py", line 307, in flush
    self._sock.sendall(view[write_offset:write_offset+buffer_size])
error: [Errno 32] Broken pipe

`
I am getting hammered with these today.  Very annoying but easy to test for you


Resolving patch:
diff --git a/runserver.py b/runserver.py
--- a/runserver.py
+++ b/runserver.py
@@ -90,9 +90,15 @@ def run(*args, **kwargs):
             raise
         except:
             exc_type, exc_value, exc_trace = sys.exc_info()
-            log.critical('Unhandled patched exception (%s): "%s".',
-                         exc_type, exc_value)
-            sys.excepthook(exc_type, exc_value, exc_trace)
+
+            # Handle Flask's broken pipe when a client prematurely ends
+            # the connection.
+            if str(exc_value) == '[Errno 32] Broken pipe':
+                pass
+            else:
+                log.critical('Unhandled patched exception (%s): "%s".',
+                             exc_type, exc_value)
+                sys.excepthook(exc_type, exc_value, exc_trace)
     Thread.run = run
 
 


Test patch: