get_columns_description wrapped DBAPI connection/operational/database
errors into a generic SupersetGenericDBErrorException before they ever
reached CreateDatasetCommand's dedicated re-raise clause, making that
clause unreachable for virtual datasets. Preserve SupersetDBAPIError
subclasses the same way OAuth2RedirectError is already preserved.
DatasetRestApi.post also flattened these deliberately-unchanged
infra failures (including SupersetTimeoutException) into the generic
except Exception -> 500 "Fatal error" branch, discarding their real
status. Handle them explicitly before that branch.
Addresses PR review comments from msyavuz on apache/superset#43334.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
get_columns_description wrapped every exception (including OAuth2RedirectError)
raised during query execution into SupersetGenericDBErrorException, so a
virtual dataset's OAuth2 challenge never reached the create.py guard meant to
preserve it. Also restore @safe's opaque-500 behavior for unexpected
exceptions on DatasetRestApi.post, since dropping @safe to let
OAuth2RedirectError through otherwise let raw exception text leak via
Flask's global error handler.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
msyavuz's review noted that CreateDatasetCommand's OAuth2RedirectError
re-raise doesn't survive the API layer: DatasetRestApi.post is wrapped
in flask-appbuilder's @safe, which catches any uncaught exception and
flattens it into an opaque 500, dropping the url/tab_id extras the
frontend needs to start the OAuth2 dance. Mirror the pattern already
used by DatabaseRestApi (no @safe + explicit except OAuth2RedirectError:
raise) so the app-level SupersetErrorException handler can build the
correct 403 response instead.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>