how can i use try and except while getting model objects? - python

I have to use a try and except block with the following code, as I am trying to get a model class object but in case if database is empty so for that I need to use try and except.
if(txStatus=='SUCCESS'):
order=Order.objects.get(id=id) #NEED TRY ACCEPT BLOCK FOR THIS
URL = payment_collection_webhook_url
request_data ={}
json_data = json.dumps(request_data)
requests.post(url = URL, data = json_data)
return Response(status=status.HTTP_200_OK)

try..except..else..finally block works like this:
try:
order=Order.objects.get(id=id)
except ObjectDoesNotExist(or MultipleObjectsReturned in case it returns more
than 1 queryset or instance):
...Handle the exception, Write any code you want
else:
...This gets called if there is no exception or error, means it will
execute right after try statement if there's no error, so if you want
something more to happen only if the code doesn't throw an error, you can
write it here
finally:
...This gets executed no matter what in any case, means if there's
something you want to execute regardless of whether it throws an
exception or not, you write it here.

It is as simple as this:
try:
order = Order.objects.get(id=order_id)
except Order.DoesNotExist:
# Exception thrown when the .get() function does not find any item.
pass # Handle the exception here.
You can find more information about DoesNotExist exception here.

#Hagyn is correct, but in Django there is another way to do that:
Something like this:
orders = Order.objects.filter(id=order_id)
if orders.exists():
order = orders.last()
else:
# do rest of the things

Related

Two identical code snippets, one of them does not work. How come?

I am trying to rewrite some of my code into functions instead, but a problem has occurred, that does not make any sense for me. I will now show the two code snippets:
Code 1:
def get_isPrivateAccount(page_source):
try:
match = re.search(r'"isPrivateAccount":(.+?)', page_source)
if match:
isPrivateAccount = match.group(1)
except Exception as e:
print('Could not find the isPrivateAccount of the user. The following exception was raised:\n', e)
return isPrivateAccount
Code 2:
page_source = driver.page_source
match = re.search(r'"isPrivateAccount":(.+?)', page_source)
if match:
is_private = match.group(1)
else:
print('Match not found')
The first code gets the page_source = driver.page_source from another function that returns it, exactly the same way written.
How come the second code snippet works perfect and can find '"isPrivateAccount":false' and return 'f' without any problem as a string, but the first code snippet cannot and says that it is 'None'? Error code from first code snippet:
cannot access local variable 'isPrivateAccount' where it is not associated with a value
As the error traceback suggests if an exception occurs then the code execution jump to the exception block and then continue till the return were isPrivateAccount.. but it is only defined if no exception occur.
def get_isPrivateAccount(page_source):
try:
match = re.search(r'"isPrivateAccount":(.+?)', page_source)
if match:
return match.group(1)
except Exception as e:
print('Could not find the isPrivateAccount of the user. The following exception was raised:\n', e)
Notice that the try/except is a bit meaningless, use instead raise and/or a custom excpetion.
def get_isPrivateAccount(page_source):
match = re.search(r'"isPrivateAccount":(.+?)', 'bjkasfdjadas')
if match:
return match.group(1)
print(Exception('Could not find the isPrivateAccount of the user. The following exception was raised:'))
#raise Excpetion(...)
You are declaring and initializing isPrivateAccount inside the if statement. If there is no match, the variable will never be defined and the return statement throws an error as you cannot access a variable which does not exist.
You have to define the variable at the top of your function:
isPrivateAccount = None

Handling different return types for Exceptions

I am working on a small texting application using Twilio API. Recently, I had some issues with the API so I added an Exception in my get_current_credits() function.
I am quite new to Python and programming in general and I would like to know what would be the cleanest way to do that.
If the Exception is throw, I only return a String. If not, I am returning a tuple. What would be the cleanest way to see what was the return from my inject_credits() function, I am thinking about type(res) but does seems a quick and dirty solution?
def get_current_credits():
try:
balance_data = twilio_client.api.v2010.balance.fetch()
balance = float(balance_data.balance)
currency = balance_data.currency
return balance, currency
except Exception:
return "503 Service Unavailable"
def inject_credit():
res = get_current_credits()
# if Exception:
# return the Exception message as a string
# else, do the following:
(credit, currency) = res
if currency != "EUR":
credit = currency_converter.convert(credit, currency, 'EUR')
return dict(credit=(round(credit,2)))
You could move the Exception outside, into the body of inject_credit. Thus, you don't have to do any if statements inside inject_credit, you can just catch the Exception there itself.
Checking the type isn't a bad idea, but it is not very clear what is being done if someone is only reading inject_credit.
You can try this:
if type(get_current_credits()) == str:
# Do something if it is a string
else:
# Do something if it is a tuple
However, the best way would be to add the try statement outside of the function so that you can catch the exception there instead.
try:
get_current_credits()
except Exception as e:
print(e)
# Do whatever

Python : How to use an error out of a try/except block?

I have this try block in my code :
try:
installation('isc-dhcp-server')
except:
print('Oops an error...')
sys.exit(8)
Here in a try/except block the sys.exit(8) will just exit this block and keep an error with code "8". This is just what I want. Now I want to use this except somehere else in a code to avoid somes parts link to this setup. How can I do that ?
I try to put the error in a variable with :
except Exception as NameofError:
And use NameofError with a if statement but this var is not defined in the local space (I think) so I can't use it.
Just initiate a variable before the try-catch block and assign the exception to it
caught_error = None
try:
# some error throwing func
except Exception as e:
caught_error = e
# your error handling code
print(caught_error)
Edit: However, if you still have sys.exit() in your catch block you probably won't have the chance to do anything to the exception given that your program will be terminated already.

Python trying fails

I am trying in Python.
try:
newbutton['roundcornerradius'] = buttondata['roundcornerradius']
buttons.append(newbutton)
buttons is a list. roundcornerradius is optional in buttondata.
Alas this gives
buttons.append(newbutton)
^ SyntaxError: invalid syntax
I just want to ignore the cases where roundcornerradius does not exist. I don't need any error reported.
why arent you using the except keyword
try:
newbutton['roundcornerradius'] = buttondata['roundcornerradius']
buttons.append(newbutton)
except:
pass
this will try the first part and if an error is thrown it will do the except part
you can also add the disered error you want to except a certain error like this
except AttributeError:
you can also get the excepted error by doing this:
except Exception,e: print str(e)
You should catch a try with exception:
try:
code may through exception
except (DesiredException):
in case of exception
Also you can use else with try if you need to populate new buttons only when try succeeds:
try:
newbutton['roundcornerradius'] = buttondata['roundcornerradius']
except KeyError:
pass
else:
buttons.append(newbutton)
single except: with no exception class defined will catch every exception raised which may not be desired in some cases.
Most probably you will get KeyError on your code but I am not sure.
See here for builtin exceptions:
http://docs.python.org/2/library/exceptions.html
You must close block with except or finally if using try.
try:
newbutton['roundcornerradius'] = buttondata['roundcornerradius']
except KeyError:
pass#omit raise if key 'roundcornerradius' does not exists
buttons.append(newbutton)
If you know default value for 'roundcornerradius' - you dont need no try ... except
newbutton['roundcornerradius'] = buttondata.get('roundcornerradius', DEFAULT_RADIUS)
buttons.append(newbutton)

In Django, how can I get an exception's message?

In a view function, I have something like:
try:
url = request.POST.get('u', '')
if len(url) == 0:
raise ValidationError('Empty URL')
except ValidationError, err:
print err
The output is a string: [u'Empty URL']
When I try to pass the error message to my template (stuffed in a dict, something like { 'error_message': err.value }), the template successfully gets the message (using {{ error_message }}).
The problem is that I get the exact same string as above, [u'Empty URL'], with the [u'...']!
How do I get rid of that?
(Python 2.6.5, Django 1.2.4, Xubuntu 10.04)
ValidationError actually holds multiple error messages.
The output of print err is [u'Empty URL'] because that is the string returned by repr(err.messages) (see ValidationError.__str__ source code).
If you want to print a single readable message out of a ValidationError, you can concatenate the list of error messages, for example:
# Python 2
print '; '.join(err.messages)
# Python 3
print('; '.join(err.messages))
If you are importing ValidationError from django.core.exceptions you can simply use messages method as err.messages.
https://github.com/django/django/blob/main/django/core/exceptions.py#L124
If you are importing ValidationError from rest_framework.serializers , there is no messages property for the ValidationError but there is detail property. so you can use err.detail which will give you a dictionary.
In order to concatenate all the error messages as a string, you can use
"".join(["".join(v) for v in err.detail.values()])
or
"".join([k+" - "+"".join(v) for k,v in err.detail.items()])
https://github.com/encode/django-rest-framework/blob/master/rest_framework/exceptions.py#L143
A more general way to always know where the message is to call the dir function on your err variable to show you all the attribute of this object.
from that list you can infer where the messages are, in my case (with django 3.2) i found out that the message dict is in an attribute called args.
so to use it (with a print for example)
try:
url = request.POST.get('u', '')
if len(url) == 0:
raise ValidationError('Empty URL')
except ValidationError, err:
print(err.args) # HERE THE ERROR DICT MESSAGE IS ACCESSIBLE
I fixed it by changing ValidationError to BaseException.

Categories