Skip to content

Commit

Permalink
Docs: Added documentation for custom errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Seluj78 committed Jun 10, 2024
1 parent 2a66a9f commit caa8406
Show file tree
Hide file tree
Showing 17 changed files with 465 additions and 63 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ tox -p

# TODO

- [ ] Documentation
- [ ] Licence
- [ ] Move todo-list to GitHub issues
- [ ] Badges
- [ ] Automatic build/deployment (https://github.com/pypa/cibuildwheel)
- [ ] https://github.com/PyCQA/flake8-bugbear
- [ ] Versioning of docs in Read the Docs
- [ ] Refactor documentation to avoid full links in docs (have `BadRequestError` instead of `flask_utils.errors.BadRequestError`)
- [ ] Add usage examples to documentation in the Usage section
8 changes: 8 additions & 0 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ This part of the documentation covers all the interfaces of Flask-Utils
Custom exceptions
-----------------

.. warning:: For any of these errors to work, you need to register the error handlers in your Flask app.
To do this, you can call :meth:`flask_utils.errors.register_error_handlers` with your Flask app as an argument.

.. code-block:: python
from flask_utils import register_error_handlers
register_error_handlers(app)
.. automodule:: flask_utils.errors
:members:

Expand Down
2 changes: 1 addition & 1 deletion flask_utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Increment versions here according to SemVer
__version__ = "0.2.4"
__version__ = "0.2.5"

from flask_utils.errors import ConflictError
from flask_utils.errors import ForbiddenError
Expand Down
26 changes: 13 additions & 13 deletions flask_utils/errors/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from flask import Flask
from flask import Response

from flask_utils.errors._error_template import generate_error_json
from flask_utils.errors._error_template import _generate_error_json
from flask_utils.errors.badrequest import BadRequestError
from flask_utils.errors.conflict import ConflictError
from flask_utils.errors.failed_dependency import FailedDependencyError
Expand Down Expand Up @@ -32,7 +32,7 @@ def generate_badrequest(error: BadRequestError) -> Response:
:param error: The error body
:return: Returns the response formatted
"""
return generate_error_json(error, 400)
return _generate_error_json(error, 400)

@application.errorhandler(ConflictError)
def generate_conflict(error: ConflictError) -> Response:
Expand All @@ -44,7 +44,7 @@ def generate_conflict(error: ConflictError) -> Response:
:return: Returns the response formatted
"""

return generate_error_json(error, 409)
return _generate_error_json(error, 409)

@application.errorhandler(ForbiddenError)
def generate_forbidden(error: ForbiddenError) -> Response:
Expand All @@ -56,7 +56,7 @@ def generate_forbidden(error: ForbiddenError) -> Response:
:return: Returns the response formatted
"""

return generate_error_json(error, 403)
return _generate_error_json(error, 403)

@application.errorhandler(NotFoundError)
def generate_notfound(error: NotFoundError) -> Response:
Expand All @@ -68,7 +68,7 @@ def generate_notfound(error: NotFoundError) -> Response:
:return: Returns the response formatted
"""

return generate_error_json(error, 404)
return _generate_error_json(error, 404)

@application.errorhandler(UnauthorizedError)
def generate_unauthorized(error: UnauthorizedError) -> Response:
Expand All @@ -80,7 +80,7 @@ def generate_unauthorized(error: UnauthorizedError) -> Response:
:return: Returns the response formatted
"""

return generate_error_json(error, 401)
return _generate_error_json(error, 401)

@application.errorhandler(OriginIsUnreachableError)
def generate_origin_is_unreachable(error: OriginIsUnreachableError) -> Response:
Expand All @@ -92,7 +92,7 @@ def generate_origin_is_unreachable(error: OriginIsUnreachableError) -> Response:
:return: Returns the response formatted
"""

return generate_error_json(error, 523)
return _generate_error_json(error, 523)

@application.errorhandler(WebServerIsDownError)
def generate_web_server_is_down(error: WebServerIsDownError) -> Response:
Expand All @@ -104,7 +104,7 @@ def generate_web_server_is_down(error: WebServerIsDownError) -> Response:
:return: Returns the response formatted
"""

return generate_error_json(error, 521)
return _generate_error_json(error, 521)

@application.errorhandler(FailedDependencyError)
def generate_failed_dependency(error: FailedDependencyError) -> Response:
Expand All @@ -116,7 +116,7 @@ def generate_failed_dependency(error: FailedDependencyError) -> Response:
:return: Returns the response formatted
"""

return generate_error_json(error, 424)
return _generate_error_json(error, 424)

@application.errorhandler(GoneError)
def generate_gone(error: GoneError) -> Response:
Expand All @@ -128,7 +128,7 @@ def generate_gone(error: GoneError) -> Response:
:return: Returns the response formatted
"""

return generate_error_json(error, 410)
return _generate_error_json(error, 410)

@application.errorhandler(UnprocessableEntityError)
def generate_unprocessable_entity(error: UnprocessableEntityError) -> Response:
Expand All @@ -140,7 +140,7 @@ def generate_unprocessable_entity(error: UnprocessableEntityError) -> Response:
:return: Returns the response formatted
"""

return generate_error_json(error, 422)
return _generate_error_json(error, 422)

@application.errorhandler(ServiceUnavailableError)
def generate_service_unavailable(error: ServiceUnavailableError) -> Response:
Expand All @@ -152,7 +152,7 @@ def generate_service_unavailable(error: ServiceUnavailableError) -> Response:
:return: Returns the response formatted
"""

return generate_error_json(error, 503)
return _generate_error_json(error, 503)


__all__ = [
Expand All @@ -161,7 +161,7 @@ def generate_service_unavailable(error: ServiceUnavailableError) -> Response:
"ForbiddenError",
"NotFoundError",
"UnauthorizedError",
"generate_error_json",
"_generate_error_json",
"FailedDependencyError",
"WebServerIsDownError",
"OriginIsUnreachableError",
Expand Down
23 changes: 21 additions & 2 deletions flask_utils/errors/_error_template.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
from flask import jsonify
from flask import Response

from flask_utils.errors.base_class import BaseFlaskException
from flask_utils.errors.base_class import _BaseFlaskException


def generate_error_json(error: BaseFlaskException, status_code: int) -> Response:
def _generate_error_json(error: _BaseFlaskException, status_code: int) -> Response:
"""
This function is used to generate a json of the error passed
:param error: The error containing the message and solution
:param status_code: The status code of the error.
:return: Returns a json containing all the info
:Example:
.. code-block:: python
from flask_utils.errors import _BaseFlaskException
from flask_utils.errors._error_template import _generate_error_json
class MyError(_BaseFlaskException):
self.name = "MyError"
self.msg = msg
self.solution = solution
self.status_code = 666
error = MyError("This is an error", "This is the solution")
json = _generate_error_json(error, 666)
.. versionadded:: 0.1.0
"""
success = False
json = {
Expand Down
42 changes: 38 additions & 4 deletions flask_utils/errors/badrequest.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,43 @@
from flask_utils.errors.base_class import BaseFlaskException
from flask_utils.errors.base_class import _BaseFlaskException


class BadRequestError(BaseFlaskException):
"""
This is the BadRequestError class for the Exception.
class BadRequestError(_BaseFlaskException):
"""This is the BadRequestError exception class.
When raised, it will return a 400 status code with the message and solution provided.
:param msg: The message to be displayed in the error.
:param solution: The solution to the error.
:Example:
.. code-block:: python
from flask_utils.errors import BadRequestError
# Inside a Flask route
@app.route('/example', methods=['POST'])
def example_route():
...
if some_condition:
raise BadRequestError("This is a bad request error.")
The above code would return the following JSON response from Flask:
.. code-block:: json
{
"success": false,
"error": {
"type": "BadRequestError",
"name": "Bad Request",
"message": "This is a bad request error.",
"solution": "Try again."
},
"code": 400
}
.. versionadded:: 0.1.0
"""

def __init__(self, msg: str, solution: str = "Try again.") -> None:
Expand Down
2 changes: 1 addition & 1 deletion flask_utils/errors/base_class.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Optional


class BaseFlaskException(Exception):
class _BaseFlaskException(Exception):
name: Optional[str] = None
msg: Optional[str] = None
solution: str = "Try again."
42 changes: 38 additions & 4 deletions flask_utils/errors/conflict.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,43 @@
from flask_utils.errors.base_class import BaseFlaskException
from flask_utils.errors.base_class import _BaseFlaskException


class ConflictError(BaseFlaskException):
"""
This is the ConflictError class for the Exception.
class ConflictError(_BaseFlaskException):
"""This is the ConflictError exception class.
When raised, it will return a 409 status code with the message and solution provided.
:param msg: The message to be displayed in the error.
:param solution: The solution to the error.
:Example:
.. code-block:: python
from flask_utils.errors import ConflictError
# Inside a Flask route
@app.route('/example', methods=['POST'])
def example_route():
...
if some_condition:
raise ConflictError("This is a conflict error.")
The above code would return the following JSON response from Flask:
.. code-block:: json
{
"success": false,
"error": {
"type": "ConflictError",
"name": "Conflict",
"message": "This is a conflict error.",
"solution": "Try again."
},
"code": 409
}
.. versionadded:: 0.1.0
"""

def __init__(self, msg: str, solution: str = "Try again.") -> None:
Expand Down
42 changes: 38 additions & 4 deletions flask_utils/errors/failed_dependency.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,43 @@
from flask_utils.errors.base_class import BaseFlaskException
from flask_utils.errors.base_class import _BaseFlaskException


class FailedDependencyError(BaseFlaskException):
"""
This is the FailedDependencyError class for the Exception.
class FailedDependencyError(_BaseFlaskException):
"""This is the FailedDependencyError exception class.
When raised, it will return a 424 status code with the message and solution provided.
:param msg: The message to be displayed in the error.
:param solution: The solution to the error.
:Example:
.. code-block:: python
from flask_utils.errors import FailedDependencyError
# Inside a Flask route
@app.route('/example', methods=['POST'])
def example_route():
...
if some_condition:
raise FailedDependencyError("This is a failed dependency error.")
The above code would return the following JSON response from Flask:
.. code-block:: json
{
"success": false,
"error": {
"type": "FailedDependencyError",
"name": "Failed Dependency",
"message": "This is a failed dependency error.",
"solution": "Try again later."
},
"code": 424
}
.. versionadded:: 0.1.0
"""

def __init__(self, msg: str, solution: str = "Try again later.") -> None:
Expand Down
42 changes: 38 additions & 4 deletions flask_utils/errors/forbidden.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,43 @@
from flask_utils.errors.base_class import BaseFlaskException
from flask_utils.errors.base_class import _BaseFlaskException


class ForbiddenError(BaseFlaskException):
"""
This is the ForbiddenError class for the Exception.
class ForbiddenError(_BaseFlaskException):
"""This is the ForbiddenError exception class.
When raised, it will return a 403 status code with the message and solution provided.
:param msg: The message to be displayed in the error.
:param solution: The solution to the error.
:Example:
.. code-block:: python
from flask_utils.errors import ForbiddenError
# Inside a Flask route
@app.route('/example', methods=['POST'])
def example_route():
...
if some_condition:
raise ForbiddenError("This is a forbidden error.")
The above code would return the following JSON response from Flask:
.. code-block:: json
{
"success": false,
"error": {
"type": "ForbiddenError",
"name": "Forbidden",
"message": "This is a forbidden error.",
"solution": "Try again."
},
"code": 403
}
.. versionadded:: 0.1.0
"""

def __init__(self, msg: str, solution: str = "Try again.") -> None:
Expand Down
Loading

0 comments on commit caa8406

Please sign in to comment.