DEV Community

Cover image for Flask Rest API -Part:4- Exception Handling

Flask Rest API -Part:4- Exception Handling

Paurakh Sharma Humagain on January 02, 2020

Part 4: Exception Handling Howdy! In the previous Part of the series, we learned how we can add authentication and authorization. In thi...
Collapse
 
atlasloewenherz profile image
atlasloewenherz • Edited

very good article! thanks

please update the above link, you current references a 404 this is the new link:

flask-restful.readthedocs.io/en/la...

a minor addition:

in the new docs its says:

"Note: Custom Exceptions must have HTTPException as the base Exception."

if i do change the errors in the dictionary to extends HTTPException instead of Exception i get:

   ~  curl -v -X POST --header 'Content-Type: application/json' -d '{"password":"Password20", "email":"user212@mail.com", "phone":"016553225644"}' 'http://127.0.0.1:8888/user/register'                                                               ✔  22:30:26 
Note: Unnecessary use of -X or --request, POST is already inferred.
*   Trying 127.0.0.1:8888...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 8888 (#0)
> POST /user/register HTTP/1.1
> Host: 127.0.0.1:8888
> User-Agent: curl/7.65.3
> Accept: */*
> Content-Type: application/json
> Content-Length: 80
>
* upload completely sent off: 80 out of 80 bytes
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: text/html
< Content-Length: 121
< Server: Werkzeug/0.16.0 Python/3.7.6
< Date: Mon, 23 Mar 2020 21:30:28 GMT
<
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>None Unknown Error</title>
<h1>Unknown Error</h1>
<p></p>
* Closing connection 0

otherwise its an http 500 error and the flask debugging views ( html)

Thanks

Collapse
 
tumluliu profile image
Lu Liu • Edited

[UPDATE]: I've found another working workaround (I think you too ;) ) : github.com/vimalloc/flask-jwt-exte...

Very nice article series! Thanks a lot for the great stuff!
One question: have you tried accessing the protected endpoints without passing the Authorization header? According to my test, it will throw a 500 instead of expected 401. It seems that the error handling framework could not catch the internal NoAuthorizationError from jwt_extended properly.
I tried one suggestion from github.com/flask-restful/flask-res... . However, it will make the situation even worse: NoAuthorizationError can be properly returned, but all other self-defined errors could not be caught. Do you have a better solution to that?

Collapse
 
paurakhsharma profile image
Paurakh Sharma Humagain

Haha glad that you found it ;) I asked the question there while writing the article and got the answer back after I have published the article.
Thanks for editing your comment to help others :)

Collapse
 
yosefco3 profile image
Yosef Cohen

Great Tutorials, thanks.
This exceptions didn't work to me, until i replaced "Exception" with "HTTPException".
maybe there was a change ....
see here the last line in the page:
flask-restful.readthedocs.io/en/la...

Collapse
 
ysasson profile image
ysasson

following the code the error was raised but did not get the friendly json message.. what is wrong?

Collapse
 
rozzah profile image
RoZZaH

I was having that trouble but if you turn debug off i.e. app.run() rather than app.run(debug=True)
it works for me

Collapse
 
paurakhsharma profile image
Paurakh Sharma Humagain

Please have a look at the GitHub link and see if you missed anything.
If it doesn't work out please let me know what you tried, and where the error occurred.

Collapse
 
birkmarcus profile image
Birk Marcus

Hi. Great articles. Cant wait till you make a frontend implementation series (as promised in ;) )
How come you havn't made a "ExpiredTokenError" in errors.py when it's raised in reset_password.py?

Collapse
 
paurakhsharma profile image
Paurakh Sharma Humagain

Oh yeah, I forgot about that promise ;)
Hopefully, I can start the frontend series soon. Before that, I want to make some improvements to this backend like adding images.

About ExpiredTokenError that's a mistake, I should add ExpiredTokenError in errors.py as well.

Collapse
 
argiriraj profile image
Giriraj AR

Hi Paurakh,

How to import in case of 2 different error modules, for example
resource_errors and user_errors?

I tried as below but its not working

from resources.errors import resource_errors
from user.errors import user_errors
api = Api(app, errors={'user_errors':user_errors, 'resource_errors':resource_errors})

Will be great if you can suggest me what i am doing wrong?

Collapse
 
argiriraj profile image
Giriraj AR

I Found a solution,

the parameter error accepts only dictionary, so merge the different error dictionary into one and then pass that dictionary
example:
collective_errors = {**user_errors, **resource_errors}
api = Api(app, errors=collective_errors)

Collapse
 
cosmokabs profile image
Cossam

Hey Paurakh Sharma Humagain I've been getting this error (TypeError: init() takes 1 positional argument but 2 were given) more often on the ListField as well as the ReferenceField. Please help me out How can i go past this error?

Collapse
 
bisscay profile image
Bissallah Ekele • Edited

Great implementation!

One quick note, you can avoid handling your exceptions with try-catch by extending the HTTPException class.
FlaskRESTful will handle these exceptions for you.

Secondly, you can avoid defining a 'pass' in error classes like InternalServerError, seeing the it already exists in Werkzeug.
FlaskRESTful will access your errors dictionary and display your JSON.

Lovely read once again, you improved my understanding.
Cheers.

Collapse
 
adityashaw profile image
Adityashaw

How do I pass some custom "message" or "info" data/fields to the Errors defined in this manner?

Collapse
 
thenakulchawla profile image
thenakulchawla

This is one of the best tutorials I have ever folowed, the best part being that everything works. I did not have to look up why things aren't working.