I have a callback that needs to do a lot of input-checking because I fully expect my users to try and put garbage data into the dash-table component.
Once done, it updates a sql database.
The callback has two ways of catching errors: First, it checks the values using if statements, and then exits the loop if the user messed up. It also shows an error in a DIV components so the user knows what they did.
The second way is simple try/except catching. If there are value errors, for example, it catches that too. The exception message is then put into the DIV so the user knows what’s wrong.
This all worked perfectly for a long time. However, I’ve updated dash several times since then, and the try/except part does not work anymore. The exception is caught, but the DIV does not update.
I can’t see the exception in the server window, but I can see the exception in the browser debugger. Example screenshot here…
edit: oh and I have app.config.suppress_callback_exceptions = True because it’s a multi page app. I hope that’s not what’s breaking it? It worked fine before…
The error is on my end but I have no idea where. (edit: not all my fault, I think? see other updates)
My code is long and messy but here’s the important bit. There are 3 buttons, and I’m using the old way of handling inputs, so this is just the relevant “if” statement:
if nclick_bt1>nclick_bt2 and nclick_bt1>nclick_bt3:
engine = create_engine(HMI_Vars.engineString, echo=False)
metadata = MetaData()
# reflect db schema to MetaData
ProgramTable = metadata.tables['Programs']
Session = orm.scoped_session(orm.sessionmaker(bind=engine))
conn = engine.connect()
rowsSQL = updateRowsforSQL(rows)
#Keep track of all the values in the "time" column, because we can't have duplicates. It's messy
#Ensure at least one value in each column
for row in rowsSQL:
ID = row.pop('ID')
if row['Time'] in times:
message.append('Duplicate Time Value. Please Correct and Try Again')
update = ProgramTable.update().values(row).where(ProgramTable.c.ID==ID)
insert = ProgramTable.insert().values(row)
except Exception as inst:
message.append(inst.args) # arguments stored in .args
So I figured out the dash_table component is trying to validate my columns even when I don’t want it to.
Big question: Why does it think it’s an int/float even though I explicitly told it to be ‘any’?
Yet more info. Here is what’s going on as far as I can figure:
- User puts in bad data
- Exception is thrown in my python code
- The exception is caught somewhere else by dash, and raises the exception in dash_render. Then, the callback stops
- Since it is raised in dash_render, I see it in the browser debugger, but not in the console.
This is different from previous versions where the callback would finish and I would get the feedback in the output DIV component.
Is there workaround? Is this intended?
so as expected it was mostly my fault.
Remember when I said I was returning the exception message so the user had feedback? Well…it was returning as a tuple and dash didn’t like that. Changing to a list solved the problem.
Not sure why dash_render was involved in this whole issue. But it REALLY did not like trying to display a tuple in my DIV.
to be more specific, it does’t like tuples inside lists. which makes sense I guess.
Basically my messages are all stored as a list, so if there’s more than 1 error it shows all of them. So this format works:
[string, string, html.Br(),string…etc]
this does NOT work:
[string, string,tuple, html.Br(),…etc]