Repository: falconry/falcon
Pull request #1066 (2017-05-26 15:43:04)

feat: Add 5xx error classes
Adds following error classes, together with tests:

- [x] 501 Not Implemented
- [x] 504 Gateway Timeout
- [x] 505 HTTP Version Not Supported

codecov[bot]: # [Codecov](https://codecov.io/gh/falconry/falcon/pull/1066?src=pr&el=h1) Report
> Merging [#1066](https://codecov.io/gh/falconry/falcon/pull/1066?src=pr&el=desc) into [master](https://codecov.io/gh/falconry/falcon/commit/5da8aad15bb150889621c1eb122202865ee21416?src=pr&el=desc) will **not change** coverage.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/falconry/falcon/pull/1066/graphs/tree.svg?src=pr&token=zOtkfNQ3h6&width=650&height=150)](https://codecov.io/gh/falconry/falcon/pull/1066?src=pr&el=tree)

```diff
@@          Coverage Diff           @@
##           master   #1066   +/-   ##
======================================
  Coverage     100%    100%           
======================================
  Files          31      31           
  Lines        2190    2193    +3     
  Branches      339     339           
======================================
+ Hits         2190    2193    +3
```


| [Impacted Files](https://codecov.io/gh/falconry/falcon/pull/1066?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [falcon/errors.py](https://codecov.io/gh/falconry/falcon/pull/1066?src=pr&el=tree#diff-ZmFsY29uL2Vycm9ycy5weQ==) | `100% <100%> (ø)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/falconry/falcon/pull/1066?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/falconry/falcon/pull/1066?src=pr&el=footer). Last update [5da8aad...4cb2fd3](https://codecov.io/gh/falconry/falcon/pull/1066?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

wssbck: @jmvrbanac @kgriffs Another PR with error classes.

Patch:
diff --git a/falcon/errors.py b/falcon/errors.py
index 4457827..73a2c97 100644
--- a/falcon/errors.py
+++ b/falcon/errors.py
@@ -1250,6 +1250,57 @@ class HTTPInternalServerError(HTTPError):
                                                       description, **kwargs)
 
 
+class HTTPNotImplemented(HTTPError):
+    """501 Not Implemented.
+
+    The 501 (Not Implemented) status code indicates that the server does
+    not support the functionality required to fulfill the request.  This
+    is the appropriate response when the server does not recognize the
+    request method and is not capable of supporting it for any resource.
+
+    A 501 response is cacheable by default; i.e., unless otherwise
+    indicated by the method definition or explicit cache controls (see
+    Section 4.2.2 of [RFC7234]).
+
+    (See also: RFC 7231, Section 6.6.2)
+
+    Keyword Args:
+        title (str): Error title (default '500 Internal Server Error').
+        description (str): Human-friendly description of the error, along with
+            a helpful suggestion or two.
+        headers (dict or list): A ``dict`` of header names and values
+            to set, or a ``list`` of (*name*, *value*) tuples. Both *name* and
+            *value* must be of type ``str`` or ``StringType``, and only
+            character values 0x00 through 0xFF may be used on platforms that
+            use wide characters.
+
+            Note:
+                The Content-Type header, if present, will be overridden. If
+                you wish to return custom error messages, you can create
+                your own HTTP error class, and install an error handler
+                to convert it into an appropriate HTTP response for the
+                client
+
+            Note:
+                Falcon can process a list of ``tuple`` slightly faster
+                than a ``dict``.
+
+        href (str): A URL someone can visit to find out more information
+            (default ``None``). Unicode characters are percent-encoded.
+        href_text (str): If href is given, use this as the friendly
+            title/description for the link (default 'API documentation
+            for this error').
+        code (int): An internal code that customers can reference in their
+            support request or to help them when searching for knowledge
+            base articles related to this error (default ``None``).
+
+    """
+
+    def __init__(self, title=None, description=None, **kwargs):
+        super(HTTPNotImplemented, self).__init__(status.HTTP_501, title,
+                                                 description, **kwargs)
+
+
 class HTTPBadGateway(HTTPError):
     """502 Bad Gateway.
 
@@ -1365,6 +1416,103 @@ class HTTPServiceUnavailable(HTTPError):
                                                      **kwargs)
 
 
+class HTTPGatewayTimeout(HTTPError):
+    """504 Gateway Timeout.
+
+    The 504 (Gateway Timeout) status code indicates that the server,
+    while acting as a gateway or proxy, did not receive a timely response
+    from an upstream server it needed to access in order to complete the
+    request.
+
+    (See also: RFC 7231, Section 6.6.5)
+
+    Keyword Args:
+        title (str): Error title (default '503 Service Unavailable').
+        description (str): Human-friendly description of the error, along with
+            a helpful suggestion or two.
+        headers (dict or list): A ``dict`` of header names and values
+            to set, or a ``list`` of (*name*, *value*) tuples. Both *name* and
+            *value* must be of type ``str`` or ``StringType``, and only
+            character values 0x00 through 0xFF may be used on platforms that
+            use wide characters.
+
+            Note:
+                The Content-Type header, if present, will be overridden. If
+                you wish to return custom error messages, you can create
+                your own HTTP error class, and install an error handler
+                to convert it into an appropriate HTTP response for the
+                client
+
+            Note:
+                Falcon can process a list of ``tuple`` slightly faster
+                than a ``dict``.
+
+        href (str): A URL someone can visit to find out more information
+            (default ``None``). Unicode characters are percent-encoded.
+        href_text (str): If href is given, use this as the friendly
+            title/description for the link (default 'API documentation
+            for this error').
+        code (int): An internal code that customers can reference in their
+            support request or to help them when searching for knowledge
+            base articles related to this error (default ``None``).
+    """
+
+    def __init__(self, title=None, description=None, **kwargs):
+        super(HTTPGatewayTimeout, self).__init__(status.HTTP_504, title,
+                                                 description, **kwargs)
+
+
+class HTTPVersionNotSupported(HTTPError):
+    """505 HTTP Version Not Supported
+
+    The 505 (HTTP Version Not Supported) status code indicates that the
+    server does not support, or refuses to support, the major version of
+    HTTP that was used in the request message.  The server is indicating
+    that it is unable or unwilling to complete the request using the same
+    major version as the client, as described in Section 2.6 of
+    [RFC7230], other than with this error message.  The server SHOULD
+    generate a representation for the 505 response that describes why
+    that version is not supported and what other protocols are supported
+    by that server.
+
+    (See also: RFC 7231, Section 6.6.6)
+
+    Keyword Args:
+        title (str): Error title (default '503 Service Unavailable').
+        description (str): Human-friendly description of the error, along with
+            a helpful suggestion or two.
+        headers (dict or list): A ``dict`` of header names and values
+            to set, or a ``list`` of (*name*, *value*) tuples. Both *name* and
+            *value* must be of type ``str`` or ``StringType``, and only
+            character values 0x00 through 0xFF may be used on platforms that
+            use wide characters.
+
+            Note:
+                The Content-Type header, if present, will be overridden. If
+                you wish to return custom error messages, you can create
+                your own HTTP error class, and install an error handler
+                to convert it into an appropriate HTTP response for the
+                client
+
+            Note:
+                Falcon can process a list of ``tuple`` slightly faster
+                than a ``dict``.
+
+        href (str): A URL someone can visit to find out more information
+            (default ``None``). Unicode characters are percent-encoded.
+        href_text (str): If href is given, use this as the friendly
+            title/description for the link (default 'API documentation
+            for this error').
+        code (int): An internal code that customers can reference in their
+            support request or to help them when searching for knowledge
+            base articles related to this error (default ``None``).
+    """
+
+    def __init__(self, title=None, description=None, **kwargs):
+        super(HTTPVersionNotSupported, self).__init__(status.HTTP_505, title,
+                                                      description, **kwargs)
+
+
 class HTTPInsufficientStorage(HTTPError):
     """507 Insufficient Storage.
 
diff --git a/falcon/status_codes.py b/falcon/status_codes.py
index 4cb6113..676e550 100644
--- a/falcon/status_codes.py
+++ b/falcon/status_codes.py
@@ -122,9 +122,9 @@ HTTP_502 = '502 Bad Gateway'
 HTTP_BAD_GATEWAY = HTTP_502
 HTTP_503 = '503 Service Unavailable'
 HTTP_SERVICE_UNAVAILABLE = HTTP_503
-HTTP_504 = '504 Gateway Time-out'
+HTTP_504 = '504 Gateway Timeout'
 HTTP_GATEWAY_TIMEOUT = HTTP_504
-HTTP_505 = '505 HTTP Version not supported'
+HTTP_505 = '505 HTTP Version Not Supported'
 HTTP_HTTP_VERSION_NOT_SUPPORTED = HTTP_505
 HTTP_507 = '507 Insufficient Storage'
 HTTP_INSUFFICIENT_STORAGE = HTTP_507


Test patch:
diff --git a/tests/test_error.py b/tests/test_error.py
index 2d398fb..73aefa9 100644
--- a/tests/test_error.py
+++ b/tests/test_error.py
@@ -20,8 +20,11 @@ import falcon.status_codes as status
     (falcon.HTTPRequestHeaderFieldsTooLarge, status.HTTP_431),
     (falcon.HTTPUnavailableForLegalReasons, status.HTTP_451),
     (falcon.HTTPInternalServerError, status.HTTP_500),
+    (falcon.HTTPNotImplemented, status.HTTP_501),
     (falcon.HTTPBadGateway, status.HTTP_502),
     (falcon.HTTPServiceUnavailable, status.HTTP_503),
+    (falcon.HTTPGatewayTimeout, status.HTTP_504),
+    (falcon.HTTPVersionNotSupported, status.HTTP_505),
     (falcon.HTTPInsufficientStorage, status.HTTP_507),
     (falcon.HTTPLoopDetected, status.HTTP_508),
     (falcon.HTTPNetworkAuthenticationRequired, status.HTTP_511),
@@ -49,9 +52,13 @@ def test_with_default_title_and_desc(err, title):
     falcon.HTTPLocked,
     falcon.HTTPFailedDependency,
     falcon.HTTPRequestHeaderFieldsTooLarge,
-    falcon.HTTPInternalServerError,
     falcon.HTTPUnavailableForLegalReasons,
+    falcon.HTTPInternalServerError,
+    falcon.HTTPNotImplemented,
     falcon.HTTPBadGateway,
+    falcon.HTTPServiceUnavailable,
+    falcon.HTTPGatewayTimeout,
+    falcon.HTTPVersionNotSupported,
     falcon.HTTPInsufficientStorage,
     falcon.HTTPLoopDetected,
     falcon.HTTPNetworkAuthenticationRequired,