Repository: sanic-org/sanic

Issue:
[Un]necessary code?
This:

https://github.com/huge-success/sanic/blob/fafe23d7c273a8329006a986dc9c73643b92e091/sanic/server.py#L153-L156

Couldn't be translated into this?

```python
exception = RequestTimeout("Request Timeout")
self.write_error(exception)
```

Another one here:

https://github.com/huge-success/sanic/blob/fafe23d7c273a8329006a986dc9c73643b92e091/sanic/server.py#L173-L176

Because there is a lot of these code patterns already in `server.py`:

https://github.com/huge-success/sanic/blob/fafe23d7c273a8329006a986dc9c73643b92e091/sanic/server.py#L202-L203

I can submit the PR, just for uniformity.


Discussion:
Stuff like this makes me wonder if I'm bad at python (high probability) or crazy (also high probability). 

Is there a reason you would try: raise and then catch the exception you raised in the try, when the raise is the only statement in the try block? I could see if we were wrapping things around the if blocks... but I'm all for leaning out the code if we can and there's no specific reason.
> Stuff like this makes me wonder if I'm bad at python (high probability) or crazy (also high probability).

That made me laugh. Welcome to the club :beers:

> Is there a reason you would try: raise and then catch the exception you raised in the try, when the raise is the only statement in the try block?

Well, no. Perhaps there might be a reason on the git history, idk. But, I'll send a PR tomorrow either way :wink:
I've seen these same patterns in server.py, and I too have (internally) questioned their purpose.
I have always assumed there is some nuanced low-level reason they are done that way.

I now have a different theory. I haven't looked back through the git history, but I think maybe the error handling section of the `server.py` file has been rewritten at some point, maybe each section was able to raise an exception, and the `write_error` was handled elsewhere, then at some point in time it was decided (for performance reasons?) to write out the error as soon as the exception is thrown, so it just ended up that way.
I can try translating those parts, if all of the tests still pass then I don't see anything wrong with removing those sections in favour of the translations.
Thanks, @ashleysommer ! I think I understood the general idea, but I don't know how I'd implement it. Anyway, if you need some help, please let me know :+1: 
I think the point is that by raising you attach a traceback

```
import traceback

def with_raise():
    try:
        raise RuntimeError('failing')
    except RuntimeError as e:
        return e

e1 = with_raise()
print('with raise')
print('\n'.join(traceback.format_exception(type(e1), e1, e1.__traceback__)))


def without_raise():
    return RuntimeError('failing')

e2 = without_raise()
print('without raise')
print('\n'.join(traceback.format_exception(type(e2), e2, e2.__traceback__)))

## -- End pasted text --
with raise
Traceback (most recent call last):

  File "<ipython-input-4-9db7dae0feba>", line 5, in with_raise
    raise RuntimeError('failing')

RuntimeError: failing

without raise
RuntimeError: failing
```

Resolving patch:
diff --git a/sanic/server.py b/sanic/server.py
--- a/sanic/server.py
+++ b/sanic/server.py
@@ -150,10 +150,7 @@ def request_timeout_callback(self):
                 self._request_stream_task.cancel()
             if self._request_handler_task:
                 self._request_handler_task.cancel()
-            try:
-                raise RequestTimeout('Request Timeout')
-            except RequestTimeout as exception:
-                self.write_error(exception)
+            self.write_error(RequestTimeout('Request Timeout'))
 
     def response_timeout_callback(self):
         # Check if elapsed time since response was initiated exceeds our
@@ -170,10 +167,7 @@ def response_timeout_callback(self):
                 self._request_stream_task.cancel()
             if self._request_handler_task:
                 self._request_handler_task.cancel()
-            try:
-                raise ServiceUnavailable('Response Timeout')
-            except ServiceUnavailable as exception:
-                self.write_error(exception)
+            self.write_error(ServiceUnavailable('Response Timeout'))
 
     def keep_alive_timeout_callback(self):
         # Check if elapsed time since last response exceeds our configured
@@ -199,8 +193,7 @@ def data_received(self, data):
         # memory limits
         self._total_request_size += len(data)
         if self._total_request_size > self.request_max_size:
-            exception = PayloadTooLarge('Payload Too Large')
-            self.write_error(exception)
+            self.write_error(PayloadTooLarge('Payload Too Large'))
 
         # Create parser if this is the first time we're receiving data
         if self.parser is None:
@@ -218,8 +211,7 @@ def data_received(self, data):
             message = 'Bad Request'
             if self._debug:
                 message += '\n' + traceback.format_exc()
-            exception = InvalidUsage(message)
-            self.write_error(exception)
+            self.write_error(InvalidUsage(message))
 
     def on_url(self, url):
         if not self.url:
@@ -233,8 +225,7 @@ def on_header(self, name, value):
         if value is not None:
             if self._header_fragment == b'Content-Length' \
                     and int(value) > self.request_max_size:
-                exception = PayloadTooLarge('Payload Too Large')
-                self.write_error(exception)
+                self.write_error(PayloadTooLarge('Payload Too Large'))
             try:
                 value = value.decode()
             except UnicodeDecodeError:
@@ -433,7 +424,7 @@ def write_error(self, exception):
                 self.log_response(response)
             try:
                 self.transport.close()
-            except AttributeError as e:
+            except AttributeError:
                 logger.debug('Connection lost before server could close it.')
 
     def bail_out(self, message, from_error=False):
@@ -443,8 +434,7 @@ def bail_out(self, message, from_error=False):
                          self.transport.get_extra_info('peername'))
             logger.debug('Exception:\n%s', traceback.format_exc())
         else:
-            exception = ServerError(message)
-            self.write_error(exception)
+            self.write_error(ServerError(message))
             logger.error(message)
 
     def cleanup(self):


Test patch: