streamlit: Unexpected behaviour of showErrorDetails = false

Summary

When setting showErrorDetails to false, the stack is displayed.

Steps to reproduce

Code snippet:

main.py

import streamlit as st
import databases
import sqlalchemy

DATABASE_URL = 'postgresql://user:pwd@server.postgres.azurr.com:5432/dbname?sslmode=prefer'
database = databases.Database(DATABASE_URL)
engine = sqlalchemy.create_engine(
    DATABASE_URL, pool_size=3, max_overflow=0
)

result_set = engine.execute('SELECT * FROM mytable')

config.toml

[client]
showErrorDetails = false

Expected behavior:

When setting showErrorDetails to false, I would expect no trace to be displayed, only a generic error message.

Actual behavior:

showErrorDetails = false This is the error message, followed by full trace:

sqlalchemy.exc.OperationalError: This app has encountered an error. The original error message is redacted to prevent data leaks. Full error details have been recorded in the logs (if you’re on Streamlit Cloud, click on ‘Manage app’ in the lower right of your app). Traceback: File “C:\Users\greg_\dev\virtualenvs\hwq_front\lib\site-packages\streamlit\script_runner.py”, line 430, in run_script exec(code, module.dict) File “D:\HWQ\dev\HWQ_FRONT\bug.py”, line 11, in <module> result_set = engine.execute(‘SELECT * FROM mytable’) File “<string>”, line 2, in execute File "C:\Users\greg\dev\virtualenvs\hwq_front\lib\site-packages\sqlalchemy\util\deprecations.py", line 401, in warned return fn(*args, **kwargs) […]

showErrorDetails = true This is the error message, followed by full trace:

OperationalError: (psycopg2.OperationalError) could not connect to server: Connection timed out Is the server running on host “hwq-server.postgres.database.azure.com” (20.73.151.139) and accepting TCP/IP connections on port 5432? (Background on this error at: https://sqlalche.me/e/14/e3q8) Traceback: File “C:\Users\greg_\dev\virtualenvs\hwq_front\lib\site-packages\streamlit\script_runner.py”, line 430, in run_script exec(code, module.dict) File “D:\HWQ\dev\HWQ_FRONT\bug.py”, line 11, in <module> result_set = engine.execute(‘SELECT * FROM mytable’) File “<string>”, line 2, in execute File "C:\Users\greg\dev\virtualenvs\hwq_front\lib\site-packages\sqlalchemy\util\deprecations.py", line 401, in warned return fn(*args, **kwargs) […]

Is this a regression?

Can’t tell, using this feature for the first time.

Debug info

  • Streamlit version: 1.6.0
  • Python version: 3.9.7
  • Using virtualenvwrapper with pip
  • OS version: Windows 10
  • Browser version: Chrome 99.0.4844.51

About this issue

  • Original URL
  • State: open
  • Created 2 years ago
  • Reactions: 14
  • Comments: 17

Most upvoted comments

+1 to regard this as a bug and would be very desirable if fixed. For production apps this is a security risk.

Will chime in here that it would be useful with this functionality to limit even what gets printed to the console in the stdout. (per my thread here on the streamlit forum). I noticed that database creds were getting printed in the exception. While showErrorDetails should theoretically hide the exception in the browser, the documentation seems to imply that the exception would still be printed in its entirety to the console. (Please correct me if I’m mistaken here.)

Also do support the original post on hiding the traceback as well as the exception. Especially with systems where our deployed applications are logged, sensitive data getting written out to stored logs (either in the exception or the traceback) in any way can become a huge no no. Would be great to be able to fully control the verbosity of the error messages on deployed applications.

Hey! We’re looking into this right now. Already wanted to do it a few months ago but it got moved due to some other projects and then I lost track of it, unfortunately.

My current plan is to fix this by

  1. hiding the traceback when showErrorDetails = false and
  2. introducing a new option showErrorDetails = "traceback", which has the current behavior (i.e. hide the exception message but show the traceback).

That way, we can keep showing the traceback on Community Cloud (which we find pretty useful for debugging but happy to hear other opinions!) and developers can turn it off completely when needed / if their app contains sensitive information directly in the code.

I still need to verify some things with the eng time but I’m hopeful we can get this done within the next few releases.

I agree that there is a mismatch between what showErrorDetails is supposed to do (per the docs / my initial understanding of it based on its name) and what it does.

Per the docs:

# If set to False, an exception will result in a generic message being shown in the browser, and exceptions and tracebacks will be printed to the console only.

As noted in this issue, the traceback does appear regardless of showErrorDetails’s value.

Thanks!

Hello @vdonato @jrieke

Thanks for handling this. I don’t think displaying the trace it is expected behaviour. When the feature was added (see https://github.com/streamlit/streamlit/pull/2770), it clearly says “uncaught exceptions in a Streamlit app will result in a generic “Something went wrong!” warning in the browser, rather than the exception and its traceback”. So the traceback should be hidden in theory.

Hi @jrieke following up on this again. I am using showErrorDetails = false but still see exception messages in the UI. Why is this the case, and what can we do to completely suppress errors/exceptions from being displayed in the UI?

Here’s another option that will disable Streamlit’s “scriptrunner” handle_uncaught_app_exception() method. I use Sentry to capture and log the exception when in production (with an environment variable DEBUG to toggle between displaying the error or logging to Sentry).

import sys
import os
from sentry_sdk import capture_exception


script_runner = sys.modules["streamlit.runtime.scriptrunner.script_runner"]
handle_uncaught_app_exception = script_runner.handle_uncaught_app_exception

def exception_handler(e):
    # Custom error handling
    if os.getenv("DEBUG", "true").lower() == "true":
        handle_uncaught_app_exception(e)
    else:
        capture_exception(e)

script_runner.handle_uncaught_app_exception = exception_handler

@vdonato I wonder if you guys plan to address this. For public-facing apps, showing the trace is not desirable, and can be unsafe. I wish that there was an option to let the uncaught exceptions bubble up so that I could catch them and deal with them the way I want. For example, I could catch it and display a sad puppy’s picture instead of st.exception. I guess a third option here, under which the exception doesn’t get handled, would be great.

+1, I agree with @senth1s and I think this is one of the issues that could block any serious team from using streamlit in a production environment.

Considering that this has been open for more than a year, can the team (maybe @jrieke ?) please provide an update on whether and when they plan to address such a big security risk (such as exposing service account credentials to the data warehouse)?

As Vincent stated above, this behavior was intentional. We wanted to give users a way to report where an error is coming from. But I can see that it could be problematic. We’re looking into it and will see if we want to change it!