Python: Exiting script [duplicate] - exit

This question already has answers here:
python sys.exit not working in try [duplicate]
(2 answers)
Closed 4 years ago.
I have a small python script which I have written specifically for this question.
#!/usr/bin/python3
import sys
def testfunc(test):
if test == 1:
print("test is 1")
else:
print("test is not 1")
sys.exit(0)
try:
testfunc(2)
except:
print("something went wrong")
print("if test is not 1 it should not print this")
What I was expecting is that when test = 2 the script should exit. Instead what I get is this;
test is not 1
something went wrong
if test is not 1 it should not print this
I am new to python but not to scripting/coding. I have searched all over the place and every answer is simply "use sys.exit()"
Well it seems that sys.exit() has what seems to be unexpected behaviour when it is contained within try/except. If I remove the try it behaves as expected
Is this normal behaviour? If so is there a way to hard exit the script with out it continuing to execute into the exception block when test = 2?
Note: this is sample code that is a simplified version of the logic I am intending to use in another script. The reason the try/except is there is because testfunc() will be called using a variable and I want to catch the exception if an invalid function name is provided
Thanks in advance
Edit: I have also tried quit(), exit(), os._exit() and raise SystemExit

Here, sys.exit(0) raises a SystemExit exception.
Since you put the calling code inside a Try-Except block, it's as expected caught. If you want to propagate the exception, recall a sys.exit() with the code status:
try:
testfunc(2)
except SystemExit as exc:
sys.exit(exc.code) # reperform an exit with the status code
except:
print("something went wrong")
print("if test is not 1 it should not print this")

Related

how to continue in a python script, if the program exits/crashes with pwntools?

I want to continue the python script do things, when the program crashes/exits. But it does not work. For example:
from pwn import *
p = process("./proc")
p.interactive()
<do stuff and exit>
print("Some stuff")
But when the progam proc exits/crashes, the part below p.interactive() is not executed. Can someone help?
you should use a "try except" which allows you to run code in the try part, and once the program crashes it moves on to the except. read more here.
an example:
try:
print(x)
except NameError:
print("Variable x is not defined")
except:
print("Something else went wrong")

Passing an specific error python [duplicate]

This question already has answers here:
Python: Catching specific exception
(3 answers)
Closed 6 years ago.
I am trying to pass a specific key error.by this two.
try:
per_visit_large_store = 100 * dic_data[mac]['Retail Store']['No. of visit to large store']/float(dic_data[mac]['Total no. of walk_in'])
except KeyError: 'Retail Store'
pass
and
try:
per_visit_large_store = 100 * dic_data[mac]['Retail Store']['No. of visit to large store']/float(dic_data[mac]['Total no. of walk_in'])
except KeyError: 'Retail Store':
pass
both of this raises Indentation and syntax error respectively. What exactly I am doing wrong? I am using python 2.7
Syntax is incorrect, it should be:
try:
# some code there
except KeyError as e:
caused_key = e.args[0]
if caused_key == 'Retail Store':
pass
See more in Python Exception tutorial
Good Luck :)!
The correct syntax is:
try:
...
except KeyError:
pass
If you want to catch a specific key then you need to check the message of the error:
d = {'a':1, 'b':2}
try:
d['c']
except KeyError as e:
if e.message == 'c':
blah
else:
raise KeyError, e
This will only continue the code if the key is 'c'. If it is not, then the error is raised.

Returning error string from a method in python

I was reading a similar question Returning error string from a function in python. While I experimenting to create something similar in an Object Oriented programming so I could learn a few more things I got lost.
I am using Python 2.7 and I am a beginner on Object Oriented programming.
I can not figure out how to make it work.
Sample code checkArgumentInput.py:
#!/usr/bin/python
__author__ = 'author'
class Error(Exception):
"""Base class for exceptions in this module."""
pass
class ArgumentValidationError(Error):
pass
def __init__(self, arguments):
self.arguments = arguments
def print_method(self, input_arguments):
if len(input_arguments) != 3:
raise ArgumentValidationError("Error on argument input!")
else:
self.arguments = input_arguments
return self.arguments
And on the main.py script:
#!/usr/bin/python
import checkArgumentInput
__author__ = 'author'
argsValidation = checkArgumentInput.ArgumentValidationError(sys.argv)
if __name__ == '__main__':
try:
result = argsValidation.validate_argument_input(sys.argv)
print result
except checkArgumentInput.ArgumentValidationError as exception:
# handle exception here and get error message
print exception.message
When I am executing the main.py script it produces two blank lines. Even if I do not provide any arguments as input or even if I do provide argument(s) input.
So my question is how to make it work?
I know that there is a module that can do that work for me, by checking argument input argparse but I want to implement something that I could use in other cases also (try, except).
Thank you in advance for the time and effort reading and replying to my question.
OK. So, usually the function sys.argv[] is called with brackets in the end of it, and with a number between the brackets, like: sys.argv[1]. This function will read your command line input. Exp.: sys.argv[0] is the name of the file.
main.py 42
In this case main.py is sys.argv[0] and 42 is sys.argv[1].
You need to identifi the string you're gonna take from the command line.
I think that this is the problem.
For more info: https://docs.python.org/2/library/sys.html
I made some research and I found this useful question/ answer that helped me out to understand my error: Manually raising (throwing) an exception in Python
I am posting the correct functional code under, just in case that someone will benefit in future.
Sample code checkArgumentInput.py:
#!/usr/bin/python
__author__ = 'author'
class ArgumentLookupError(LookupError):
pass
def __init__(self, *args): # *args because I do not know the number of args (input from terminal)
self.output = None
self.argument_list = args
def validate_argument_input(self, argument_input_list):
if len(argument_input_list) != 3:
raise ValueError('Error on argument input!')
else:
self.output = "Success"
return self.output
The second part main.py:
#!/usr/bin/python
import sys
import checkArgumentInput
__author__ = 'author'
argsValidation = checkArgumentInput.ArgumentLookupError(sys.argv)
if __name__ == '__main__':
try:
result = argsValidation.validate_argument_input(sys.argv)
print result
except ValueError as exception:
# handle exception here and get error message
print exception.message
The following code prints: Error on argument input! as expected, because I violating the condition.
Any way thank you all for your time and effort, hope this answer will help someone else in future.

How can a django 1.6 app recover from database outage?

I have a django 1.6 application with a long running daemon process, that need to handle database outages gracefully. I am using the django.db.backends.postgresql_psycopg2 engine.
What I have tried so far is that after I have handled a DatabaseError and logged it, I try to close the database connection, wait for some time and let the next transaction create a new connection.
That is not working out well for me. The following code demonstrates the problem:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from core.models import User
from django.db import close_connection
from django.db.transaction import atomic
from time import sleep
#atomic(savepoint=False)
def do_something():
u = User.objects.get(username='brian')
sleep(3)
u.set_unusable_password()
u.save()
try: do_something()
except Exception as e: print 'A:', e
try: close_connection()
except Exception as e: print 'B:', e
sleep(3)
try: do_something()
except Exception as e: print 'C:', e
If the database connection goes down during the sleep call in the first transaction, and recovers during the sleep call between the two transactions, I see this:
A: connection already closed
B: connection already closed
C: The outermost 'atomic' block cannot use savepoint = False when autocommit is off.
If I use savepoint=True instead, the output looks slightly different:
A: connection already closed
B: connection already closed
C: connection already closed
What I found so far is that the first exception is raised by __exit__ in the atomic decorator. Presumably this is masking an exception raised by set_unusable_password.
The second exception is raised when close_connection try to call abort.
The final exception is raised by __enter__ in the atomic decorator before it even tries to communicate with the database server.
What do I need to do more than calling close_connection() in order to clean up old state, such that I can establish a new connection to the database?
It turns out close_connection is deprecated. I found this in the source:
def close_connection(**kwargs):
warnings.warn(
"close_connection is superseded by close_old_connections.",
PendingDeprecationWarning, stacklevel=2)
Using close_old_connections instead of close_connection doesn't change anything. The problem behaved exactly the same. The source of close_old_connections did look promising though:
def close_old_connections(**kwargs):
for conn in connections.all():
# Remove this when the legacy transaction management goes away.
try:
conn.abort()
except DatabaseError:
pass
conn.close_if_unusable_or_obsolete()
Turns out the problem shows up in conn.abort() which apparently is only there to support legacty transaction management. It seems from the code that exceptions from conn.abort can be safely ignored. But in my case conn.abort doesn't raise a DatabaseError rather it raises InterfaceError.
If I copy the implementation of close_old_connections into my own code and modify it to handle both DatabaseError and InterfaceError, my symptoms do go away.
I found one known bug, which is somewhat related to my problem.
After looking into what actually happens inside close_connection and close_old_connections I came up with the following lines, which as far as I can tell do the right thing:
try: django.db.connection.abort()
except django.db.utils.Error: pass
django.db.connection.close()

Python try except else invalid syntax?

So I am trying to set up a small script in Python's IDLE. The IDLE syntax check tells me this code has a syntax error:
from ftplib import FTP
import os
def ftpconnect(address, username, password):
ftp_connection = 0
ftp = FTP(address)
try:
ftp.login(username, password)
print(ftp.getwelcome())
if ftp.getwelcome() == '220 FTP Connected!':
return 1
else:
return 0
print(ftpconnect('10.10.10.xxx', 'xxx', 'xxx'))
The syntax error comes anywhere that I try to get out of the "try" statement, here being the "else:" line. I've looked around and it seems like I have the right syntax...any thoughts?
Thanks! I'm running Python 2, not 3.
In addition to the problem with my syntax (missing except statement entirely), my ftp attempt statement was outside of the try block. Since I was not "try"ing it, it failed anyway.