Make SHOW_STACKTRACE config apply across the board (#7845)

This commit is contained in:
Maxime Beauchemin 2019-07-12 08:58:44 -07:00 committed by GitHub
parent 5ebc5a69d9
commit 87f50ba0d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 40 additions and 24 deletions

View File

@ -18,7 +18,6 @@
from datetime import datetime, timedelta
import logging
import pickle as pkl
import traceback
from typing import Dict, List
import numpy as np
@ -199,7 +198,7 @@ class QueryContext:
if not error_message:
error_message = "{}".format(e)
status = utils.QueryStatus.FAILED
stacktrace = traceback.format_exc()
stacktrace = utils.get_stacktrace()
if is_loaded and cache_key and cache and status != utils.QueryStatus.FAILED:
try:

View File

@ -102,7 +102,9 @@ WTF_CSRF_EXEMPT_LIST = ["superset.views.core.log"]
DEBUG = os.environ.get("FLASK_ENV") == "development"
FLASK_USE_RELOAD = True
# Whether to show the stacktrace on 500 error
# Superset allows server-side python stacktraces to be surfaced to the
# user when this feature is on. This may has security implications
# and it's more secure to turn it off in production settings.
SHOW_STACKTRACE = True
# Extract and use X-Forwarded-For/X-Forwarded-Proto headers?
@ -309,10 +311,8 @@ DEFAULT_MODULE_DS_MAP = OrderedDict(
ADDITIONAL_MODULE_DS_MAP = {}
ADDITIONAL_MIDDLEWARE = []
"""
1) https://docs.python-guide.org/writing/logging/
2) https://docs.python.org/2/library/logging.config.html
"""
# 1) https://docs.python-guide.org/writing/logging/
# 2) https://docs.python.org/2/library/logging.config.html
# Console Log Settings
@ -404,10 +404,8 @@ class CeleryConfig(object):
CELERY_CONFIG = CeleryConfig
"""
# Set celery config to None to disable all the above configuration
CELERY_CONFIG = None
"""
# CELERY_CONFIG = None
# Additional static HTTP headers to be served by your Superset server. Note
# Flask-Talisman aplies the relevant security HTTP headers.

View File

@ -32,6 +32,7 @@ import signal
import smtplib
import sys
from time import struct_time
import traceback
from typing import List, NamedTuple, Optional, Tuple
from urllib.parse import unquote_plus
import uuid
@ -41,7 +42,7 @@ import bleach
import celery
from dateutil.parser import parse
from dateutil.relativedelta import relativedelta
from flask import flash, Flask, g, Markup, render_template
from flask import current_app, flash, Flask, g, Markup, render_template
from flask_appbuilder.security.sqla.models import User
from flask_babel import gettext as __
from flask_babel import lazy_gettext as _
@ -1185,3 +1186,8 @@ def shortid() -> str:
class DatasourceName(NamedTuple):
table: str
schema: str
def get_stacktrace():
if current_app.config.get("SHOW_STACKTRACE"):
return traceback.format_exc()

View File

@ -66,8 +66,7 @@ def get_error_msg():
def json_error_response(msg=None, status=500, stacktrace=None, payload=None, link=None):
if not payload:
payload = {"error": "{}".format(msg)}
if stacktrace and conf.get("SHOW_STACKTRACE"):
payload["stacktrace"] = stacktrace
payload["stacktrace"] = utils.get_stacktrace()
if link:
payload["link"] = link
@ -125,20 +124,20 @@ def handle_api_exception(f):
return json_error_response(
utils.error_msg_from_exception(e),
status=e.status,
stacktrace=traceback.format_exc(),
stacktrace=utils.get_stacktrace(),
link=e.link,
)
except SupersetException as e:
logging.exception(e)
return json_error_response(
utils.error_msg_from_exception(e),
stacktrace=traceback.format_exc(),
stacktrace=utils.get_stacktrace(),
status=e.status,
)
except Exception as e:
logging.exception(e)
return json_error_response(
utils.error_msg_from_exception(e), stacktrace=traceback.format_exc()
utils.error_msg_from_exception(e), stacktrace=utils.get_stacktrace()
)
return functools.update_wrapper(wraps, f)

View File

@ -21,7 +21,6 @@ import inspect
import logging
import os
import re
import traceback
from typing import Dict, List # noqa: F401
from urllib import parse
@ -3261,11 +3260,9 @@ class Superset(BaseSupersetView):
return self.json_response(schemas_allowed_processed)
except Exception:
return json_error_response(
(
"Failed to fetch schemas allowed for csv upload in this database! "
"Please contact Superset Admin!\n\n"
"The error message returned was:\n{}"
).format(traceback.format_exc())
"Failed to fetch schemas allowed for csv upload in this database! "
"Please contact Superset Admin!",
stacktrace=utils.get_stacktrace(),
)

View File

@ -31,7 +31,6 @@ import logging
import math
import pickle as pkl
import re
import traceback
import uuid
from dateutil import relativedelta as rdelta
@ -423,7 +422,7 @@ class BaseViz(object):
if not self.error_message:
self.error_message = "{}".format(e)
self.status = utils.QueryStatus.FAILED
stacktrace = traceback.format_exc()
stacktrace = utils.get_stacktrace()
if (
is_loaded

View File

@ -22,12 +22,14 @@ import uuid
import numpy
from superset import app
from superset.exceptions import SupersetException
from superset.utils.core import (
base_json_conv,
convert_legacy_filters_into_adhoc,
datetime_f,
get_since_until,
get_stacktrace,
json_int_dttm_ser,
json_iso_dttm_ser,
JSONEncodedDict,
@ -763,3 +765,19 @@ class UtilsTestCase(unittest.TestCase):
def test_parse_js_uri_path_items_item_optional(self):
self.assertIsNone(parse_js_uri_path_item(None))
self.assertIsNotNone(parse_js_uri_path_item("item"))
def test_get_stacktrace(self):
with app.app_context():
app.config["SHOW_STACKTRACE"] = True
try:
raise Exception("NONONO!")
except Exception:
stacktrace = get_stacktrace()
self.assertIn("NONONO", stacktrace)
app.config["SHOW_STACKTRACE"] = False
try:
raise Exception("NONONO!")
except Exception:
stacktrace = get_stacktrace()
assert stacktrace is None