This question already has an answer here:
Why do I get a `NameError` (or `UnboundLocalError`) from using a named exception after the `except` block?
(1 answer)
Closed 17 days ago.
I've looked at other questions regarding this particular error but in those cases there was a route in the process where the variable is never defined and hence fails when called later. However with my program I set the variables before the try method, have those variables changed in the try method under certain criteria, and then an if statement calls them later but fails. When Python reaches the if statement and tries to create the variable text, it claims the variables error and error1 are undefined (referenced before assignment).
err = 0
error = 'No Error Set'
error1 = 'No Error1 Set'
try:
conn = sqlite3.connect(db_dir)
for row in conn.execute("select max(date) from eod"):
mxdate = row
if mxdate == None:
pass
else:
for row in conn.execute('select date, status from eod where date = ?',(mxdate,)):
_lst_eod = row
for row in conn.execute("select * from temp"):
_crnt_eod = row
conn.close()
except Exception as error:
error = str(error)
err = 1
logged = 0
try:
conn.close()
time = str(right_datetime())[11:19].replace(':','')
conn = sqlite3.connect(db_dir)
conn.execute("insert into error_log (date, user, auth, error, _action) values (?,?,?,?,'Failed to select from eod/temp tables.')",(int(str(_date)+time),cred[0],cred[1],error,))
conn.commit()
conn.close()
logged = 1
except Exception as error1:
error1 = str(error1)
if err == 1:
#An error occured here.
text = '##Error## An error occured while trying to end the day:\n'+error
if logged == 0:
text = text+'\n\nA row was written to the error log.'
else:
text = text+'\n\nWrite to Error Log failed due to error:\n'+error1
else:
....carry on with the rest of the program.
In Python 3, the variable to which you assign the exception in a except SomeException as e: statement is deleted on exiting the except block:
>>> e = "something"
>>> try:
... 1/0
... except ZeroDivisionError as e:
... print(e)
...
division by zero
>>> e
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'e' is not defined
The same thing's happening in your code: the except Exception as error: and except Exception as error1: blocks are deleting error and error1 when they exit.
Related
KeyError exception object contains args attribute. This is a list and it contains a key name which user tries to access within a dictionary.
Is it possible to figure out dictionary name which does not contain that key and which caused an exception while trying to access the key within it?
Example
data = {"my_key": "my_value"}
try:
data["unknown_key"] except KeyError as e:
print("key name: ", e.args[0])
print("dictionary name: ", e.???) # Here I would need to know the the name of a variable which stores the dictionary is "data"
You can kinda hack this with Python 3.11+, since the traceback contains fine-grained information about where the error happened.
import ast
import linecache
import traceback
data = {"my_key": "my_value"}
flurk = data
try:
data["flep"] = data["my_key"] + flurk["unknown_key"]
except KeyError as e:
# Find the last frame where the exception occurred, formatted as a FrameSummary
err_frame = traceback.TracebackException.from_exception(e).stack[-1]
if err_frame.lineno == getattr(err_frame, "end_lineno", -1): # If we can reliably find the line,
# ... read the line,
line = linecache.getline(err_frame.filename, err_frame.lineno)
# find the "marked segment" in it,
fragment = line[err_frame.colno:err_frame.end_colno]
# ... and parse it as an expression.
expr: ast.Expression = ast.parse(fragment, mode='eval')
# Check we're dealing with a subscript (index) node...
assert isinstance(expr.body, ast.Subscript)
# ... and extract the main parts of the expression.
subscriptee = ast.unparse(expr.body.value)
subscript = ast.unparse(expr.body.slice)
else:
subscriptee = None # No idea
subscript = e.args[0] # Just use the exception message
raise RuntimeError(f"KeyError with {subscriptee=!r}, {subscript=!r}") from e
prints out
Traceback (most recent call last):
File "scratch_679.py", line 8, in <module>
data["flep"] = data["my_key"] + flurk["unknown_key"]
~~~~~^^^^^^^^^^^^^^^
KeyError: 'unknown_key'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "scratch_679.py", line 27, in <module>
raise RuntimeError(f"KeyError with {subscriptee=!r}, {subscript=!r}") from e
RuntimeError: KeyError with subscriptee='flurk', subscript="'unknown_key'"
so you can see the subscriptee name is flurk.
I have a block of code where exception is happening for some records while executing an imported method (pls see below). My goal is NOT to stop execution, but perhaps print (to understand what's wrong with the data) some values when in error and continue. I tried various way to use "try...except", but no luck! Can someone pls take a look and suggest? Many thanks in advance!
code below
if student_name not in original_df_names_flat:
for org in orgs:
data = calculate(org, data)
result = imported_module.execute(data) # here's the line where exception happens
return result
else:
return data
if student_name not in original_df_names_flat:
for org in orgs:
data = calculate(org, data)
result = None # May fail to get assigned if error in imported_module
try:
result = imported_module.execute(data) # here's the line where exception happens
except Exception as e:
print(f'{e}') # probably better to log the exception
return result
else:
return data
I guess an exception can occur in 2 places. So try this. It covers your exception line and the other possibility. So your program should keep running.
Secondly I have adjusted the indentation of the second try clause so the loop processes all data in orgs. To return all results I have added a list 'results'.
if student_name not in original_df_names_flat:
results = []
for org in orgs:
try:
data = calculate(org, data)
except Exception as e:
print(str(e))
try:
result = imported_module.execute(data) # here's the line where exception happens
results.append(result)
except Exception as e:
print(str(e))
return results
else:
return data
the below solution took care of the problem:
if student_name not in original_df_names_flat:
for org in orgs:
data = calculate(org, data)
try:
result = imported_module.execute(data) # here's the line where exception happens
except exception as e:
print ("exception happened", e)
pass
return data
return result
else:
return data
the above solution took care of the problem
Program description:
Program accepts a file name and a segment, consisting of two numbers (each divided by one space). Then it outputs all lines from existing file where their indicies lie within the given segment.
My solution:
import sys
try:
par = input("Input (<file> <low border of the segment> <high border of the segment>): ").split(' ')
print(17 * '-')
f = par[0]
f_lines = [line.strip("\n") for line in f if line != "\n"]
length = len(f_lines)
if (par == ''):
raise RuntimeError('Error: undefined')
if (par[2] == None) or (par[2] == ''):
raise RuntimeError('Error: segment is limited')
if ((par[1] and par[2]) == None) or ((par[1] and par[2]) == ''):
raise RuntimeError('Error: segment undefined')
if (int(par[2]) >= length):
raise RuntimeError('Error: segment can not be greater than length the amount of lines')
if (par[1] == ''):
a = 0
if (par[2] == ''):
b = 0
segment = [int(par[1]), (int(par[2]) + 1)]
with open(par[0]) as f:
data = f.read().splitlines()
for k in range(segment[0], segment[1]):
print(data[k])
except (FileNotFoundError, IOError, NameError):
print('[!] Error: your input is incorrect. The file may be missing or something else. \n[?] For further information see full error logs: \n',sys.exc_info())
except RuntimeError as e:
print(e)
Problem:
When I try running my program in different ways to test each of my Runtime errors I always get this message:
Traceback (most recent call last):
File "C:\Users\1\Desktop\IT\pycharm\sem_2.py", line 10, in <module>
if (par[2] == None) or (par[2] == ''):
IndexError: list index out of range
I cannot wrap my head around how can I properly handle multiple Runtime errors so they would display as a text message. I haven't found any solution to my question anywhere online, so I'm trying to ask here.
I will appreciate any help, thanks in advance.
Your code would catch FileNotFoundError, IOError, NameError and RuntimeError but what is actually thrown is IndexError and that is not handled.
You may want to add IndexError it to the first except block:
except (FileNotFoundError, IOError, NameError, IndexError):
print('[!] Error: input incorrect!') # ^^^^^^^^^^^^
or perhaps add another except block if you want a custom message for IndexError:
except (FileNotFoundError, IOError, NameError):
print('[!] Error: input incorrect!')
except IndexError:
print('[!] Error: IndexError just happened!')
By the way, the following will always be False because the code in parentheses will resolve to a bool first, which can either be True or False and these are obviously never equal to '' or None:
((par[1] and par[2]) == None) or ((par[1] and par[2]) == '')
You may way want to rewrite it to:
(par[1] is None and par[2] is None) or (par[1] == '' and par[2] == '')
The below function parses the cisco command output,stores the output in dictionary and returns the value for a given key. This function works as expected when the dictionary contains the output. However, if the command returns no output at all the length of dictionary is 0 and the function returns a key error . I have used exception KeyError: But this doesn't seem to work.
from qa.ssh import Ssh
import re
class crypto:
def __init__(self, username, ip, password, machinetype):
self.user_name = username
self.ip_address = ip
self.pass_word = password
self.machine_type = machinetype
self.router_ssh = Ssh(ip=self.ip_address,
user=self.user_name,
password=self.pass_word,
machine_type=self.machine_type
)
def session_status(self, interface):
command = 'show crypto session interface '+interface
result = self.router_ssh.cmd(command)
try:
resultDict = dict(map(str.strip, line.split(':', 1))
for line in result.split('\n') if ':' in line)
return resultDict
except KeyError:
return False
test script :
obj = crypto('uname', 'ipaddr', 'password', 'router')
out = obj.session_status('tunnel0')
status = out['Peer']
print(status)
Error
Traceback (most recent call last):
File "./test_parser.py", line 16, in <module>
status = out['Peer']
KeyError: 'Peer'
The KeyError did not happend in the function session_status,it is happend in your script at status = out['Peer'].So your try and except in session_status will not work.you should make a try and except for status = out['Peer']:
try:
status = out['Peer']
except KeyError:
print 'no Peer'
or :
status = out.get('Peer', None)
Your exception is not in the right place. As you said you just return an empty dictionary with your function. The exception is trying to lookup the key on empty dictionary object that is returned status = outertunnel['Peer']. It might be easier to check it with the dict get function. status = outertunnel.get('Peer',False) or improve the test within the function session_status, like testing the length to decide what to return False if len(resultDict) == 0
This explains the problem you're seeing.
The exception happens when you reference out['Peer'] because out is an empty dict. To see where the KeyError exception can come into play, this is how it operates on an empty dict:
out = {}
status = out['Peer']
Throws the error you're seeing. The following shows how to deal with an unfound key in out:
out = {}
try:
status = out['Peer']
except KeyError:
status = False
print('The key you asked for is not here status has been set to False')
Even if the returned object was False, out['Peer'] still fails:
>>> out = False
>>> out['Peer']
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
out['Peer']
TypeError: 'bool' object is not subscriptable
I'm not sure how you should proceed, but dealing with the result of session_status not having the values you need is the way forward, and the try: except: block inside the session_status function isn't doing anything at the moment.
I have a piece of code that acts as a listener of a button and evaluates whether some fields above this button are filled in:
def goListener(self):
if all( [self.nme.get() != "", self.dsc.get() != "", self.imp.get != ""] ):
name = self.nme.get()
desc = self.dsc.get()
while True:
try:
imp = int(self.imp.get())
break
except:
imp = int(self.imp.get())
When I run this program with different fields filled in or otherwise, it gets it right and produces the error message I ask it to with every combination except where nme and dsc are filled in but imp isn't, this produces the error message:
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
return self.func(*args)
File "C:\Python33\todo.py", line 68, in goListener
imp = int(self.imp.get())
ValueError: invalid literal for int() with base 10: ''
This is running the except block by the way, which it shouldn't. Is this a problem with the evaluation, or am I missing something here?
You have:
self.imp.get != ""
You are failing to invoke the .get() method. Try:
self.imp.get() != ""
If imp = int(self.imp.get()) throws an error, calling it again outside of a try block will throw the same error.
The except block is for code that should run when there is an exception:
try:
imp = int(self.imp.get())
break
except:
print "Something bad happened"