Issues with loop error handling

Hi All,

I am trying to go through a loop and test if I have a wall that has a parameter that matches a parameter I input, it all works well except the follow,.

What I want to do is have a for loop, then have a try loop then start another for loop within the base for loop. But the issue I seem to be getting with the try, is that when it breaks, it breaks out of the any of the other things that may happen within this loop, for example, the secondary for loop that follows does not run.

I hope this makes sense- but if anyone has any experience with try loops and them not breaking out of the full code that would be amazing.

Sam

Hi Sam,

let me see is I get this. you do something like this structure:

for something in aList:
    try:
        for somethingElse in anotherList:
            doSomething() #this crashes
    except:
        #do something if crashes

and ones something crashes, the second for loop doesn’t continue.

If so! This is because you do the second For loop in the Try.
If you want the Second For loop to continue, you have to do the Try inside the Second For loop:

for something in aList:
    for somethingElse in anotherList:
        try:
            doSomething() #this crashes
        except:
             #do something if crashes

TIP: Post pictures or example scripts!

Hi @Joelmick

So essentially my master for loop is looking line by line through a list of dictionaries (there are a series of parameters on each of these lines which matches a wall).

For each line, I then want to try and see if I can call a wall element which matches this parameter, I use try because I do not necessarily have a wall that matches it.

At the moment, once my try has worked… I then enter another for loop which calls each item within the full line of the list im calling in the first loop.

What I ideally want to do is have the following structure_

    1. Loop over each line of my data list
  • 2 . Try and call the relevent wall, if I can get it I add to paramter if not I continue

    1. Do my secondary loop

I have just made this as a test, putting the try that is causing my issues inside another try, but surely this is not the best way? Can you tell me, if once a try is accepted, does it always break out- ie. does the try always need to be the last in line?

LOOP OVER THE DICTIONARIES (CSV LINE DATA) AND PULL UP THE PARAMETER KEY TO MATCH

tester =

updatefamilyname = IN[6]
typename_input01_value = IN[7]
typename_input02_value = IN[8]

for datarow_dict in Data_DictionaryList:

# Get matching value from data row dictionary

Matching_Value = str(datarow_dict[parameter_key_tomatch])

tester.append("test if this runs at start")
#test.append(parameter_key_tomatch)
#test.append(Matching_Value)

try: 
    try: 
		print ("here")
		Get_Matching_Value_LongIndex = Base_MatchingWalls_Dict[Matching_Value]
		Split_Index = Get_Matching_Value_LongIndex.split(indexplacesplit)[1]
		MatchedWall = Base_MatchingWalls[int(Split_Index)]
		tester.append(Matching_Value)
		tester.append(MatchedWall)
		
    	
    except: 
    	tester.append(Matching_Value)
    	#tester.append("here")
    	print ("here")
    	
    
    tester.append("test if this runs at end")
    
except: 
	tester.append(Matching_Value)
	#tester.append("here")
	print ("here")

I am sorry but seems you only posted half your code and I don’t follow what you try to do without more context. Let me see if I follow:

You loop over a List with Dictionaries
    for each Dictionary1 you have a Matching_Value
    you Try to find this Matching_Value in Dictonary2
        If you find a value you do something with it
        
        If you the Matching_Value does not exist, you get an error and this triggers the Except?

As a first tip: Try to avoid Try-Except statements as much as possible, because: If something goes wrong, you don’t get an error, because Python catches these for you.

Second tip: If you cannot avoid them, always Print the Error!

#not a practical way of debugging
try:
    DoSomething()
except:
    print("There is an error")

#A better way of Debugging
try:
    DoSomething()
except Exception as exception:
    print("There is an error: " + exception.Message) 

This way, if there is an error, you see what the error says and you can fix it. In the screenshot below you can see how you can do this in Dynamo. Mind the Namespaces

Since I only got half of the python code, I copied you code and placed comments after the lines.

tester = []

updatefamilyname = IN[6]
typename_input01_value = IN[7]
typename_input02_value = IN[8]

for datarow_dict in Data_DictionaryList:

    # Get matching value from data row dictionary
    Matching_Value = str(datarow_dict[parameter_key_tomatch])

    tester.append("test if this runs at start")
    #test.append(parameter_key_tomatch)
    #test.append(Matching_Value)

    try: #this Try will never fail. I'll Call this Try 1
        try: #I will call this Try 2
            print ("here")
            Get_Matching_Value_LongIndex = Base_MatchingWalls_Dict[Matching_Value] #This could already trigger you Try2 Except2 because "Matching_Value" does not Exist in "Base_MatchingWalls_Dict". 
            Split_Index = Get_Matching_Value_LongIndex.split(indexplacesplit)[1] #This one will always fail, because "indexplacesplit" does not Exist in the current context 
            MatchedWall = Base_MatchingWalls[int(Split_Index)] #This can fail if "Split_Index" is not a number
            tester.append(Matching_Value) 
            tester.append(MatchedWall)
            
            
        except: #I will call this Except 2
            tester.append(Matching_Value)
            #tester.append("here")
            print ("here")
            
        
        tester.append("test if this runs at end") # this will never fail, so Except 1 will never get triggered
        
    except: #I will call this Except 1
        tester.append(Matching_Value)
        print ("here")

You can deal with most of the errors in the code in other ways. e.g. if you want to check if a certain value exists in a dictionary, you can do it like below, instead of Trying to find it and if it doesn’t exist it returns an error.

tester = []

updatefamilyname = IN[6]
typename_input01_value = IN[7]
typename_input02_value = IN[8]

for datarow_dict in Data_DictionaryList:

    # Get matching value from data row dictionary
    Matching_Value = str(datarow_dict[parameter_key_tomatch])
    
    
    tester.append(Matching_Value) 
    
    # you want to check if "Matching_Value" exists in the Dictionary "Base_MatchingWalls_Dict"
    if Base_MatchingWalls_Dict.Keys.Contains(Matching_Value):
        Get_Matching_Value_LongIndex = Base_MatchingWalls_Dict[Matching_Value] 
        Split_Index = Get_Matching_Value_LongIndex.split(indexplacesplit)[1] #This one will always fail, because "indexplacesplit" does not Exist in the current context 
        MatchedWall = Base_MatchingWalls[int(Split_Index)] #This can fail if "Split_Index" is not a number
        tester.append(MatchedWall)
    else:
        #Well "Matching_Value" does not exist in "Base_MatchingWalls_Dict"
        print("The Matching_Value did not Exist in the Base_MatchingWalls_Dict")
        pass

Sorry for the long awnser!

1 Like

Thankyou, I will spend time to read.

But one big thing- can you actually print on the dynamo module! I always do this if I am just using an editor, but I didnt think you could print (I have been appending to lists, and putting them to the OUT variable).

Printing would be a big help (I couldnt believe it wasnt an option).
Sam

Printing directly to console isn’t possible, although it is possible to redirect stdout to either a .txt file (which I have done in the past) or, which I recently found out, to a StringIO object.

Borrowing largely from this webpage, I have also found that you can print the full stack traceback as well. I was looking into redirecting stderr, but there seems to be very little information in regard to that specifically in IronPython.

import sys
sys.path.append(r'C:\Program Files (x86)\IronPython 2.7\Lib')
import StringIO
import traceback
from pprint import pprint

stdout_restore = sys.stdout
stdout_redirect = StringIO.StringIO()

# Set stdout to a StringIO object
sys.stdout = stdout_redirect

print 'example'

try:
	a = 'a' - 2 # Will raise exception
except Exception as e:
	exc_type, exc_value, exc_tb = sys.exc_info()
	pprint(traceback.format_exception(exc_type, exc_value, exc_tb))

OUT = stdout_redirect.getvalue()

# Restore stdout to sys.stdout
sys.stdout = stdout_restore

Without being able to redirect stderr, any uncaught exceptions may prevent OUT = stdout_redirect.getvalue() from actually being executed, but it’s just a minor inconvenience.

1 Like

No you cannot print. I always use an debug list which I fill with strings.

@Joelmick, I assume you mean you just append it to a list and Output the list as OUT?

My issue is if any error happens, often the list doesnt even output and then I dont get to see any debug… am I missing something here? The script stop
s running and it just outputs nothing.

@cgartland I assume that is the stringIO you have below your script node in the image?

Yes, that is what is returned by StringIO.getvalue()

Yes that is what I mean.
Create a debug list and add that to the OUT variable. You can append strings to that list to see what happends.

If you still have problems, try sharing a sample project with a dynamo graph so people get a feeling for your problem and try solutions before suggesting them.

1 Like

My answer was not to follow a Try with another loop. I managed to get rid of all my Trys, but using if statements to filter down my list.

Sam

1 Like