mirror of https://github.com/apache/superset.git
feat: more SIP-40 errors (#15482)
This commit is contained in:
parent
ffa51753e3
commit
e606477ec1
|
@ -311,3 +311,19 @@ The results stored in the backend were stored in a different format, and no long
|
|||
```
|
||||
|
||||
The query results were stored in a format that is no longer supported. Please re-run your query.
|
||||
|
||||
## Issue 1035
|
||||
|
||||
```
|
||||
Failed to start remote query on a worker.
|
||||
```
|
||||
|
||||
The query was not started by an asynchronous worker. Please reach out to your administrator for further assistance.
|
||||
|
||||
## Issue 1036
|
||||
|
||||
```
|
||||
The database was deleted.
|
||||
```
|
||||
|
||||
The operation failed because the database referenced no longer exists. Please reach out to your administrator for further assistance.
|
||||
|
|
|
@ -57,6 +57,7 @@ export const ErrorTypeEnum = {
|
|||
|
||||
// Other errors
|
||||
BACKEND_TIMEOUT_ERROR: 'BACKEND_TIMEOUT_ERROR',
|
||||
DATABASE_NOT_FOUND_ERROR: 'DATABASE_NOT_FOUND_ERROR',
|
||||
|
||||
// Sqllab error
|
||||
MISSING_TEMPLATE_PARAMS_ERROR: 'MISSING_TEMPLATE_PARAMS_ERROR',
|
||||
|
@ -67,6 +68,7 @@ export const ErrorTypeEnum = {
|
|||
INVALID_CVAS_QUERY_ERROR: 'INVALID_CVAS_QUERY_ERROR',
|
||||
SQLLAB_TIMEOUT_ERROR: 'SQLLAB_TIMEOUT_ERROR',
|
||||
RESULTS_BACKEND_ERROR: 'RESULTS_BACKEND_ERROR',
|
||||
ASYNC_WORKERS_ERROR: 'ASYNC_WORKERS_ERROR',
|
||||
|
||||
// Generic errors
|
||||
GENERIC_COMMAND_ERROR: 'GENERIC_COMMAND_ERROR',
|
||||
|
|
|
@ -35,6 +35,10 @@ export default function setupErrorMessages() {
|
|||
ErrorTypeEnum.BACKEND_TIMEOUT_ERROR,
|
||||
TimeoutErrorMessage,
|
||||
);
|
||||
errorMessageComponentRegistry.registerValue(
|
||||
ErrorTypeEnum.DATABASE_NOT_FOUND_ERROR,
|
||||
DatabaseErrorMessage,
|
||||
);
|
||||
errorMessageComponentRegistry.registerValue(
|
||||
ErrorTypeEnum.GENERIC_DB_ENGINE_ERROR,
|
||||
DatabaseErrorMessage,
|
||||
|
@ -83,6 +87,10 @@ export default function setupErrorMessages() {
|
|||
ErrorTypeEnum.RESULTS_BACKEND_ERROR,
|
||||
DatabaseErrorMessage,
|
||||
);
|
||||
errorMessageComponentRegistry.registerValue(
|
||||
ErrorTypeEnum.ASYNC_WORKERS_ERROR,
|
||||
DatabaseErrorMessage,
|
||||
);
|
||||
errorMessageComponentRegistry.registerValue(
|
||||
ErrorTypeEnum.SQLLAB_TIMEOUT_ERROR,
|
||||
DatabaseErrorMessage,
|
||||
|
|
|
@ -66,6 +66,7 @@ class SupersetErrorType(str, Enum):
|
|||
|
||||
# Other errors
|
||||
BACKEND_TIMEOUT_ERROR = "BACKEND_TIMEOUT_ERROR"
|
||||
DATABASE_NOT_FOUND_ERROR = "DATABASE_NOT_FOUND_ERROR"
|
||||
|
||||
# Sql Lab errors
|
||||
MISSING_TEMPLATE_PARAMS_ERROR = "MISSING_TEMPLATE_PARAMS_ERROR"
|
||||
|
@ -76,6 +77,7 @@ class SupersetErrorType(str, Enum):
|
|||
INVALID_CVAS_QUERY_ERROR = "INVALID_CVAS_QUERY_ERROR"
|
||||
SQLLAB_TIMEOUT_ERROR = "SQLLAB_TIMEOUT_ERROR"
|
||||
RESULTS_BACKEND_ERROR = "RESULTS_BACKEND_ERROR"
|
||||
ASYNC_WORKERS_ERROR = "ASYNC_WORKERS_ERROR"
|
||||
|
||||
# Generic errors
|
||||
GENERIC_COMMAND_ERROR = "GENERIC_COMMAND_ERROR"
|
||||
|
@ -131,6 +133,8 @@ ISSUE_CODES = {
|
|||
"The results stored in the backend were stored in a "
|
||||
"different format, and no longer can be deserialized."
|
||||
),
|
||||
1035: _("Failed to start remote query on a worker."),
|
||||
1036: _("The database was deleted."),
|
||||
}
|
||||
|
||||
|
||||
|
@ -163,6 +167,8 @@ ERROR_TYPES_TO_ISSUE_CODES_MAPPING = {
|
|||
SupersetErrorType.OBJECT_DOES_NOT_EXIST_ERROR: [1029],
|
||||
SupersetErrorType.SYNTAX_ERROR: [1030],
|
||||
SupersetErrorType.RESULTS_BACKEND_ERROR: [1031, 1032, 1033],
|
||||
SupersetErrorType.ASYNC_WORKERS_ERROR: [1035],
|
||||
SupersetErrorType.DATABASE_NOT_FOUND_ERROR: [1011, 1036],
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ class SupersetErrorException(SupersetException):
|
|||
class SupersetGenericErrorException(SupersetErrorException):
|
||||
"""Exceptions that are too generic to have their own type"""
|
||||
|
||||
def __init__(self, message: str) -> None:
|
||||
def __init__(self, message: str, status: Optional[int] = None) -> None:
|
||||
super().__init__(
|
||||
SupersetError(
|
||||
message=message,
|
||||
|
@ -61,6 +61,8 @@ class SupersetGenericErrorException(SupersetErrorException):
|
|||
level=ErrorLevel.ERROR,
|
||||
)
|
||||
)
|
||||
if status is not None:
|
||||
self.status = status
|
||||
|
||||
|
||||
class SupersetErrorFromParamsException(SupersetErrorException):
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# pylint: disable=comparison-with-callable, line-too-long, too-many-branches
|
||||
import dataclasses
|
||||
import logging
|
||||
import re
|
||||
from contextlib import closing
|
||||
|
@ -2035,10 +2036,21 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
|||
table_name = data["datasourceName"]
|
||||
database_id = data["dbId"]
|
||||
except KeyError:
|
||||
return json_error_response("Missing required fields", status=400)
|
||||
raise SupersetGenericErrorException(
|
||||
"One or more required fields are missing in the request. Please try "
|
||||
"again, and if the problem persists conctact your administrator.",
|
||||
status=400,
|
||||
)
|
||||
database = db.session.query(Database).get(database_id)
|
||||
if not database:
|
||||
return json_error_response("Database not found", status=400)
|
||||
raise SupersetErrorException(
|
||||
SupersetError(
|
||||
message="The database was not found.",
|
||||
error_type=SupersetErrorType.DATABASE_NOT_FOUND_ERROR,
|
||||
level=ErrorLevel.ERROR,
|
||||
),
|
||||
status=404,
|
||||
)
|
||||
table = (
|
||||
db.session.query(SqlaTable)
|
||||
.filter_by(database_id=database_id, table_name=table_name)
|
||||
|
@ -2101,7 +2113,14 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
|||
stats_logger.incr(
|
||||
f"deprecated.{self.__class__.__name__}.select_star.database_not_found"
|
||||
)
|
||||
return json_error_response("Not found", 404)
|
||||
raise SupersetErrorException(
|
||||
SupersetError(
|
||||
message="The database was not found.",
|
||||
error_type=SupersetErrorType.DATABASE_NOT_FOUND_ERROR,
|
||||
level=ErrorLevel.ERROR,
|
||||
),
|
||||
status=404,
|
||||
)
|
||||
schema = utils.parse_js_uri_path_item(schema, eval_undefined=True)
|
||||
table_name = utils.parse_js_uri_path_item(table_name) # type: ignore
|
||||
if not self.appbuilder.sm.can_access_table(database, Table(table_name, schema)):
|
||||
|
@ -2114,7 +2133,18 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
|||
table_name,
|
||||
schema,
|
||||
)
|
||||
return json_error_response("Not found", 404)
|
||||
raise SupersetErrorException(
|
||||
SupersetError(
|
||||
message=__(
|
||||
"You are not authorized to fetch samples from this table. If "
|
||||
"you think this is an error, please reach out to your "
|
||||
"administrator."
|
||||
),
|
||||
error_type=SupersetErrorType.QUERY_SECURITY_ACCESS_ERROR,
|
||||
level=ErrorLevel.ERROR,
|
||||
),
|
||||
status=403,
|
||||
)
|
||||
stats_logger.incr(f"deprecated.{self.__class__.__name__}.select_star.success")
|
||||
return json_success(
|
||||
database.select_star(
|
||||
|
@ -2425,15 +2455,21 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
|||
)
|
||||
except Exception as ex: # pylint: disable=broad-except
|
||||
logger.exception("Query %i: %s", query.id, str(ex))
|
||||
msg = _(
|
||||
"Failed to start remote query on a worker. "
|
||||
"Tell your administrator to verify the availability of "
|
||||
"the message queue."
|
||||
|
||||
message = _("Failed to start remote query on a worker.")
|
||||
error = SupersetError(
|
||||
message=message,
|
||||
error_type=SupersetErrorType.ASYNC_WORKERS_ERROR,
|
||||
level=ErrorLevel.ERROR,
|
||||
)
|
||||
error_payload = dataclasses.asdict(error)
|
||||
|
||||
query.set_extra_json_key("errors", [error_payload])
|
||||
query.status = QueryStatus.FAILED
|
||||
query.error_message = msg
|
||||
query.error_message = message
|
||||
session.commit()
|
||||
return json_error_response("{}".format(msg))
|
||||
|
||||
raise SupersetErrorException(error)
|
||||
|
||||
# Update saved query with execution info from the query execution
|
||||
QueryDAO.update_saved_query_exec_info(query_id)
|
||||
|
@ -2638,9 +2674,23 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
|||
try:
|
||||
query.raise_for_access()
|
||||
except SupersetSecurityException as ex:
|
||||
message = _(
|
||||
"You are not authorized to see this query. If you think this "
|
||||
"is an error, please reach out to your administrator."
|
||||
)
|
||||
error = SupersetError(
|
||||
message=message,
|
||||
error_type=SupersetErrorType.QUERY_SECURITY_ACCESS_ERROR,
|
||||
level=ErrorLevel.ERROR,
|
||||
)
|
||||
error_payload = dataclasses.asdict(error)
|
||||
|
||||
query.set_extra_json_key("errors", [error_payload])
|
||||
query.status = QueryStatus.FAILED
|
||||
query.error_message = message
|
||||
session.commit()
|
||||
return json_errors_response([ex.error], status=403)
|
||||
|
||||
raise SupersetErrorException(error, status=403) from ex
|
||||
|
||||
try:
|
||||
template_processor = get_template_processor(
|
||||
|
@ -2657,7 +2707,7 @@ class Superset(BaseSupersetView): # pylint: disable=too-many-public-methods
|
|||
'The query contains one or more malformed template parameters. Please check your query and confirm that all template parameters are surround by double braces, for example, "{{ ds }}". Then, try running your query again.'
|
||||
),
|
||||
error=SupersetErrorType.INVALID_TEMPLATE_PARAMS_ERROR,
|
||||
)
|
||||
) from ex
|
||||
|
||||
if is_feature_enabled("ENABLE_TEMPLATE_PROCESSING"):
|
||||
# pylint: disable=protected-access
|
||||
|
|
|
@ -1197,7 +1197,7 @@ class TestCore(SupersetTestCase):
|
|||
self.login(username="gamma")
|
||||
example_db = utils.get_example_database()
|
||||
resp = self.client.get(f"/superset/select_star/{example_db.id}/birth_names")
|
||||
self.assertEqual(resp.status_code, 404)
|
||||
self.assertEqual(resp.status_code, 403)
|
||||
|
||||
@mock.patch("superset.views.core.results_backend_use_msgpack", False)
|
||||
@mock.patch("superset.views.core.results_backend")
|
||||
|
|
Loading…
Reference in New Issue