Issues with catching requests exceptions - python-2.7

I'm creating delete request to webserver and trying to catch the exceptions like below:
try:
response = req.delete(path, auth=HTTPBasicAuth(config.user(), config.password()), params=params, headers=headers, verify=True)
except requests.HTTPError as he:
raise SystemExit(he)
except requests.ConnectionError as ce:
raise SystemExit(ce)
except requests.URLRequired as ue:
raise SystemExit(ue)
except requests.Timeout as te:
raise SystemExit(te)
except requests.RequestException as err:
print('Undefined error: ', err)
print(response.status_code)
But delete is not processed and response.status_code prints 400, but error handling does not work. Any ideas why the error handling is not working there?

If you want to catch http errors (e.g. 401 Unauthorized) to raise exceptions, you need to call Response.raise_for_status. That will raise an HTTPError, if the response was an http error.
try:
response = req.delete(path, auth=HTTPBasicAuth(config.user(), config.password()), params=params, headers=headers, verify=True)
except requests.HTTPError as he:
raise SystemExit(he)

Related

Django Rest Framework - PermissionDenied raises 500 status code

i am working with django rest framework and want to raise a PermissionDenied exception and return a 403 response to user:
raise PermissionDenied("Custom exception message")
But it returns a 500 status code...
Can anybody explain?
thanks!

Using multiprocessing.Pool with exception handling

from multiprocessing import Pool
def f(arg):
if arg == 1:
raise Exception("exception")
return "hello %s" % arg
p = Pool(4)
res = p.map_async(f,(1,2,3,4))
p.close()
p.join()
res.get()
Consider this contrived example where I am creating a process pool of 4 workers and assigning work in f(). My question was:
How can I retrieve the successful work that was done for arguments 2,3,4 (and at the same time do exception handling for argument 1) ?
As is the code just gives me:
Traceback (most recent call last):
File "process_test.py", line 13, in <module>
res.get()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/pool.py", line 567, in get
raise self._value
Exception: exception
You can also just do the error handling in the work function
def do_work(x):
try:
return (None, something_with(x))
except Exception as e:
return (e, None)
output = Pool(n).map(do_work, input)
for exc, result in output:
if exc:
handle_exc(exc)
else:
handle_result(result)
You can use the imap function.
iterator = p.imap(f, (1,2,3,4,5))
while True:
try:
print next(iterator)
except StopIteration:
break
except Exception as error:
print error

How to return HTTP 400 response in Django?

I want to return a HTTP 400 response from my django view function if the request GET data is invalid and cannot be parsed.
How do I do this? There does not seem to be a corresponding Exception class like there is for 404:
raise Http404
From my previous comment :
You can return a HttpResponseBadRequest
Also, you can create an Exception subclass like Http404 to have your own Http400 exception.
You can do the following:
from django.core.exceptions import SuspiciousOperation
raise SuspiciousOperation("Invalid request; see documentation for correct paramaters")
SuspiciousOperation is mapped to a 400 response around line 207 of https://github.com/django/django/blob/master/django/core/handlers/base.py
If you're using the Django Rest Framework, you have two ways of raising a 400 response in a view:
from rest_framework.exceptions import ValidationError, ParseError
raise ValidationError
# or
raise ParseError
Since Django 3.2, you can also raise a BadRequest exception:
from django.core.exceptions import BadRequest
raise BadRequest('Invalid request.')
This may be better in some cases than SuspiciousOperation mentioned in another answer, as it does not log a security event; see the doc on exceptions.

Django 1.4 Local 500 Error Page

Since moving to Django 1.4 with DEBUG = True and TEMPLATE_DEBUG = True, I no longer see the typical yellow error screen with traceback when I encounter an error locally. Instead I get a plain white screen that says, "An error has occurred. Please check your logs . . . ". Is this the new behavior or have I screwed something up by combining 1.3 and 1.4 files and settings.
Here's an example of my local settings.
The error handler
is located in django.core.handler.base try to debug the handle_uncaught_exception function.
def handle_uncaught_exception(self, request, resolver, exc_info):
"""
Processing for any otherwise uncaught exceptions (those that will
generate HTTP 500 responses). Can be overridden by subclasses who want
customised 500 handling.
Be *very* careful when overriding this because the error could be
caused by anything, so assuming something like the database is always
available would be an error.
"""
from django.conf import settings
if settings.DEBUG_PROPAGATE_EXCEPTIONS:
raise
logger.error('Internal Server Error: %s', request.path,
exc_info=exc_info,
extra={
'status_code': 500,
'request': request
}
)
if settings.DEBUG:
from django.views import debug
check if you pass here
return debug.technical_500_response(request, *exc_info)
# If Http500 handler is not installed, re-raise last exception
if resolver.urlconf_module is None:
raise exc_info[1], None, exc_info[2]
# Return an HttpResponse that displays a friendly error message.
callback, param_dict = resolver.resolve500()
return callback(request, **param_dict)
check with the debugger that you pass in debug.technical_500_response

Heroku - Django raise TemplateDoesNotExist(name) exception, but template is not needed in requested action

I got a strange heroku behavior.
My code:
def generate(request, page_id):
page = get_object_or_404(Page, pk=page_id)
response = HttpResponse(page.content)
response['Content-Type'] = 'text/plain'
return response
works as I expect on dev, but on heroku it raises an exception
GET test.herokuapp.com/generate/1 dyno=web.1 queue=0 wait=0ms service=908ms status=500 bytes=59
2012-07-29T19:20:06+00:00 app[web.1]: raise TemplateDoesNotExist(name)
2012-07-29T19:20:06+00:00 app[web.1]: TemplateDoesNotExist: 500.html
and returns proper output ;) Only this one action is wrong. Other actions where I use
return render_to_response('front/home.html')
are Ok. What could be wrong?
That code throws an unhandled exception, which, outside of debug mode, makes Django display an error page that uses template 500.html. You apparently have no such template, so the exception handler raises another exception, which is the one you're seeing.