1

As per the flask-restful doc, it calls handle_error() function on any 400 or 500 error that happens on a Flask-RESTful route. So I tried to handle exceptions through out my application using this call back, thinking it would leverage multiple try catch block in my application. But while raising custom exception(ResourceNotFound) from a model raises another exception TypeError: Object of type ResourceNotFound is not JSON serializable

from werkzeug.exceptions import HTTPException
from flask_restful import Api
class ExtendedAPI(Api):
    def handle_error(self, err):
        """
        This class overrides 'handle_error' method of 'Api' class ,
        to extend global exception handing functionality of 'flask-restful'
        and helps preventing writing unnecessary
        try/except block though out the application
        """
        # import pdb; pdb.set_trace()
        logger.error(err)
        # Handle HTTPExceptions
        if isinstance(err, HTTPException):
            return jsonify({
                'message': getattr(
                    err, 'description', HTTP_STATUS_CODES.get(err.code, '')
                )
            }), err.code
        if isinstance(err, ValidationError):
            resp = {
                'success': False,
                'errors': err.messages
            }
            return jsonify(resp), 400
        # If msg attribute is not set,
        # consider it as Python core exception and
        # hide sensitive error info from end user
        # if not getattr(err, 'message', None):
        #     return jsonify({
        #         'message': 'Server has encountered some error'
        #     }), 500
        # Handle application specific custom exceptions
        return jsonify(**err.kwargs), err.http_status_code

Custom exception:

class Error(Exception):
    """Base class for other exceptions"""
    def __init__(self, http_status_code: int, *args, **kwargs):
        # If the key `msg` is provided, provide the msg string
        # to Exception class in order to display
        # the msg while raising the exception
        self.http_status_code = http_status_code
        self.kwargs = kwargs
        msg = kwargs.get('msg', kwargs.get('message'))
        if msg:
            args = (msg,)
            super().__init__(args)
        self.args = list(args)
        for key in kwargs.keys():
            setattr(self, key, kwargs[key])


class ResourceNotFound(Error):
    """Should be raised in case any resource is not found in the DB"""

The handle_error function handles HTTPException, marshmallow validation errors and the last statement to handle my custom exceptions. but using pdb, I saw the err object received by handle_error() differs from the custom exception I raised from the model. Not able to figure out any solution for this. Any thoughts on solving this problem or any different approach I can follow??

AYUSH SENAPATI
  • 309
  • 4
  • 7
  • Possible duplicate of [How to make a class JSON serializable](https://stackoverflow.com/questions/3768895/how-to-make-a-class-json-serializable) – djnz Nov 10 '19 at 19:46
  • @dylanj.nz I don't understand why flask is even trying to serialise my custom exception. I have overridden handle_error() to handle my custom exceptions and to jsonify possible exceptions. Many people follow this approach to handle exceptions globally. Check this [https://github.com/flask-restful/flask-restful/issues/280#issuecomment-51473640] – AYUSH SENAPATI Nov 11 '19 at 06:20

0 Answers0