Source code for flask_resty.exceptions

import traceback

import flask
from werkzeug.exceptions import default_exceptions

from .utils import iter_validation_errors

# -----------------------------------------------------------------------------


[docs]class ApiError(Exception): """An API exception. When raised, Flask-RESTy will send an HTTP response with the provided `status_code` and the provided `errors` under the ``errors`` property as JSON. If :py:attr:`flask.Flask.debug` or :py:attr:`flask.Flask.testing` is True, the body will also contain the full traceback under the ``debug`` property. :param int status_code: The HTTP status code for the error response. :param dict errors: A list of dict with error data. """ def __init__(self, status_code, *errors): self.status_code = status_code self.body = {"errors": errors or self.get_default_errors(status_code)} if flask.current_app.debug or flask.current_app.testing: self.body["debug"] = traceback.format_exc() @classmethod def from_http_exception(cls, exc): return cls(exc.code, cls.get_error_from_http_exception(exc)) @classmethod def get_default_errors(cls, status_code): if status_code not in default_exceptions: return () exc = default_exceptions[status_code]() return (cls.get_error_from_http_exception(exc),) @classmethod def get_error_from_http_exception(cls, exc): return { "code": "_".join(word.lower() for word in exc.name.split()), "detail": exc.description, } @classmethod def from_validation_error( cls, status_code, error, format_validation_error ): return cls( status_code, *( format_validation_error(message, path) for message, path in iter_validation_errors(error.messages) ), )
[docs] def update(self, additional): """Add additional metadata to the error. Can be chained with further updates. :param dict additional: The additional metadata :return: The :py:class:`ApiError` that :py:meth:`update` was called on :rtype: :py:class:`ApiError` """ for error in self.body["errors"]: error.update(additional) # Allow e.g. `raise e.update(additional)`. return self
@property def response(self): if flask.current_app.config.get("RESTY_TRAP_API_ERRORS"): raise self return flask.jsonify(self.body), self.status_code