-
Notifications
You must be signed in to change notification settings - Fork 102
Added support for error handling #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Hi @thinkingserious ! I have added custom exception handling. Do suggest changes for improvements. |
Hi @w- ! Have a look at this. What do you think? :) |
Hey guys, i'll be out of town on vacation for the next few days. won't be able to respond on this topic till then. |
Thanks for the heads up @w- and I hope you enjoy the vacation :) |
@w-, Do you have time to take a look? Thanks! |
In the meantime, how about I add tests for this? With Regards, |
Please add the test in the existing file. Thanks! |
python_http_client/__init__.py
Outdated
@@ -1 +1,2 @@ | |||
from .client import Client | |||
from .exceptions import * |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
even though there are many classes., I would change this to an explicit import
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
python_http_client/exceptions.py
Outdated
503 : ServiceUnavailableError | ||
} | ||
|
||
def handle_error(error): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should probably get_HTTPError(error) and it should return an instance of the specific error class instead of raising it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Umm.. Can you give an example? I can't visualize this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is what i think the function should be
def get_HTTPError(error):
try:
http_err_obj = err_dict[error.code](error)
except KeyError:
http_err_obj = HttpError(error)
return http_err_obj
python_http_client/exceptions.py
Outdated
} | ||
|
||
def handle_error(error): | ||
exc = err_dict[error.code](error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we want a try/catch here in event that the error.code doesn't match anything in our dict. it should then set err as a generic HTTPError
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I just put in a few errors, the ones that SendGrid servers returns, just for showing the approach. If approved, I will add the rest of the error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was pressing the wrong button earlier so my comments are split up.
Good work @dibyadas
python_http_client/exceptions.py
Outdated
|
||
def handle_error(error): | ||
exc = err_dict[error.code](error) | ||
exc.__cause__ = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
as per https://www.python.org/dev/peps/pep-3134/
we probably want __cause__ to be the original error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we won't to do this then an ugly traceback is produced in Python 3. In this PR, we are raising our custom exception when an urllib.HTTPError is raised. Here, in python 3 , such a thing will be displayed the output.
Traceback (most recent call last):
File "/home/dibya/workspace/python-http-client/python_http_client/client.py", line 141, in _make_request
return opener.open(request)
File "/usr/lib/python3.5/urllib/request.py", line 472, in open
response = meth(req, response)
File "/usr/lib/python3.5/urllib/request.py", line 582, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python3.5/urllib/request.py", line 504, in error
result = self._call_chain(*args)
File "/usr/lib/python3.5/urllib/request.py", line 444, in _call_chain
result = func(*args)
File "/usr/lib/python3.5/urllib/request.py", line 696, in http_error_302
return self.parent.open(new, timeout=req.timeout)
File "/usr/lib/python3.5/urllib/request.py", line 472, in open
response = meth(req, response)
File "/usr/lib/python3.5/urllib/request.py", line 582, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib/python3.5/urllib/request.py", line 510, in error
return self._call_chain(*args)
File "/usr/lib/python3.5/urllib/request.py", line 444, in _call_chain
result = func(*args)
File "/usr/lib/python3.5/urllib/request.py", line 590, in http_error_default
raise HTTPError(req.full_url, code, msg, hdrs, fp)
urllib.error.HTTPError: HTTP Error 401: UNAUTHORIZED
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "test.py", line 7, in <module>
r = a.name.api.get()
File "/home/dibya/workspace/python-http-client/python_http_client/client.py", line 209, in http_request
return Response(self._make_request(opener, request))
File "/home/dibya/workspace/python-http-client/python_http_client/client.py", line 143, in _make_request
handle_error(err)
File "/home/dibya/workspace/python-http-client/python_http_client/exceptions.py", line 53, in handle_error
raise exc
python_http_client.exceptions.UnauthorizedError: HTTP Error 401: UNAUTHORIZED
If we set the __cause__
to None, then only the part below During handling of the above exception, another exception occurred:
is shown, which is all that should be displayed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. ok. I guess it is preferable to be None
python_http_client/exceptions.py
Outdated
def __init__(self,error): | ||
self.code = error.code | ||
self.reason = error.reason | ||
#self.headers = error.headers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
both headers and body are important to record in the new HTTPError object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The HTTPError thrown by urllib
module doesn't have a body attribute and in python versions <= 3.3, they don't have the headers attribute as well. I just commented this out so that this can be discussed further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it does. you have to read docs and look at the source.
HTTPError is based on URLError which has the following attributes
err.url
err.code
err.hdrs
# to get the body
err.read()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! Since it was not mentioned in the documentation, I missed it. Thanks for the tip! :)
python_http_client/exceptions.py
Outdated
class HTTPError(Exception): | ||
''' Base of all other errors''' | ||
def __init__(self,error): | ||
self.code = error.code |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keeping in line with other http libraries, I think that self.code should actually be self.status_code. personal preference only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure we can. It'll be more evident.
python_http_client/client.py
Outdated
try: | ||
return opener.open(request) | ||
except HTTPError as err: | ||
handle_error(err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@w- Here, I am handling the urllib.HTTPError. What you are saying is, we do this:-
try:
return opener.open(request)
except HTTPError as err:
raise get_HTTPError(err)
Am I right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correct.
Hi @thinkingserious and @w- , Edit :- After pushing an commit the coverage passed but is now failing 😕 I not really familiar with this. I need some help here. With Best Regards, |
Hi @thinkingserious, With Regards, |
I'm ok with this. |
Hi @thinkingserious, |
Per sendgrid/sendgrid-python#323 if we could get examples of these awesome new exceptions in the README so other devs don't need to go surfing into tests to see examples of exceptions and what can cause them, I think that'd be super helpful. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please check code using flake8/pep8
pass | ||
|
||
class MethodNotAllowedError(HTTPError): | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could you please use spaces and pep8
Custom exceptions for
python_http_client
have been added. Only few exceptions have been added.Others will be added soon.