0

I'm trying to develop a rest api by flask-restful. The following decorator is implemented:

def errorhandler(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except errors.DocNotFound:
            abort(404, message="Wrong document requested", status=404)
    return wrapper

And, Following https://docs.python.org/2/tutorial/errors.html#user-defined-exceptions , in another file named error.py (which is imported here), I have these classes:

class DocError(Exception):
       pass

class DocNotFound(DocError):
       pass

Now my problem is the implementation of these 2 classes in a way that return my optional error msg. But I don't know how to do that. Would you please give me a hint?

P.S. Here is the way I wanna use the decorator in my Resources:

my_decorators = [
    errorhandler,
    # Other decorators
]
class Docs(Resource):
    method_decorators = my_decorators

    def get():
       from .errors import DocNotFound
       if (<something>):
             raise DocNotFound('No access for you!')
       return marshal(......)

    def delete():
        pass

    def put():
        pass

    def post():
        pass

Thanks

Birish
  • 5,514
  • 5
  • 32
  • 51

1 Answers1

1

You can raise your custom exceptions with an argument:

raise DocNotFound('The document "foo" is on the verboten list, no access for you!')

then access that message with:

except errors.DocNotFound as err:
    message = err.message or "Wrong document requested"
    abort(404, description=message)

The abort(404) call maps to a werkzeug.exceptions.NotFound exception; the description argument lets you override the default description.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks for reply. I added it as you said and it didn't work. It returns the following `code` error: NameError: "global name 'DocNotFound' is not defined" `code`. I wanna use this "errorhandler" as a decorator. And I guess it doesn't need the 'raise' :/ I'll add my Resource definition to my question. – Birish Oct 24 '14 at 17:32
  • @Sarah you do need to import your custom exception wherever you use it! – Martijn Pieters Oct 24 '14 at 17:49
  • I'm not sure if I did it right but it doesn't work...! I added it to my get() method (check it in main question). This time it doesn't go inside the get() method at all and immediately returns: HTTP/1.0 500 INTERNAL SERVER ERROR – Birish Oct 24 '14 at 18:08
  • @Sarah: you use `errorhandler.DocNotFound` in one place, `errors.DocNotFound` in another; are you certain the imports are correct? – Martijn Pieters Oct 24 '14 at 18:15
  • There are two separated files: errors.py file (which has two empty DocError and DocNotFound classes as I wrote in my question), restapi.py file (which has the errorhandler decorator and my resources). I tried import both from errorhandler `code`import DocNotFound and `code`from errors import DocumentNotFound, but non of them worked :( – Birish Oct 25 '14 at 09:15
  • You were right. I made a mistake while I was importing. I was importing `from errors import DocNotFound`, while I should import `from .errors import DocNotFound`. ThankssSssSssss :) – Birish Oct 30 '14 at 18:20
  • Wont work as same as this when you deploy it using twisted or uWSGI using aync switch – Harsh Daftary Nov 02 '14 at 16:33
  • 1
    @HarshDaftary: raising exceptions within Flask still stays within the same child process and / or thread, whatever mode you pick in your WSGI server. – Martijn Pieters Nov 02 '14 at 16:55