text: # Licensed to the Apache Software Foundation (ASF) under one
  # or more contributor license agreements.  See the NOTICE file
  # distributed with this work for additional information
  # regarding copyright ownership.  The ASF licenses this file
  # to you under the Apache License, Version 2.0 (the
  # "License"); you may not use this file except in compliance
  # with the License.  You may obtain a copy of the License at
  #
  #   http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing,
  # software distributed under the License is distributed on an
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  # KIND, either express or implied.  See the License for the
  # specific language governing permissions and limitations
  # under the License.
  # pylint: disable=too-few-public-methods,invalid-name
  from dataclasses import dataclass  # pylint: disable=wrong-import-order
  from enum import Enum
  from typing import Any, Dict, Optional
  
  from flask_babel import gettext as _
  
  
  class SupersetErrorType(str, Enum):
      """
      Types of errors that can exist within Superset.
  
      Keep in sync with superset-frontend/src/components/ErrorMessage/types.ts
      and docs/src/pages/docs/Miscellaneous/issue_codes.mdx
      """
  
      # Frontend errors
      FRONTEND_CSRF_ERROR = "FRONTEND_CSRF_ERROR"
      FRONTEND_NETWORK_ERROR = "FRONTEND_NETWORK_ERROR"
      FRONTEND_TIMEOUT_ERROR = "FRONTEND_TIMEOUT_ERROR"
  
      # DB Engine errors
      GENERIC_DB_ENGINE_ERROR = "GENERIC_DB_ENGINE_ERROR"
      COLUMN_DOES_NOT_EXIST_ERROR = "COLUMN_DOES_NOT_EXIST_ERROR"
      TABLE_DOES_NOT_EXIST_ERROR = "TABLE_DOES_NOT_EXIST_ERROR"
      SCHEMA_DOES_NOT_EXIST_ERROR = "SCHEMA_DOES_NOT_EXIST_ERROR"
      CONNECTION_INVALID_USERNAME_ERROR = "CONNECTION_INVALID_USERNAME_ERROR"
      CONNECTION_INVALID_PASSWORD_ERROR = "CONNECTION_INVALID_PASSWORD_ERROR"
      CONNECTION_INVALID_HOSTNAME_ERROR = "CONNECTION_INVALID_HOSTNAME_ERROR"
      CONNECTION_PORT_CLOSED_ERROR = "CONNECTION_PORT_CLOSED_ERROR"
      CONNECTION_HOST_DOWN_ERROR = "CONNECTION_HOST_DOWN_ERROR"
      CONNECTION_ACCESS_DENIED_ERROR = "CONNECTION_ACCESS_DENIED_ERROR"
      CONNECTION_UNKNOWN_DATABASE_ERROR = "CONNECTION_UNKNOWN_DATABASE_ERROR"
      CONNECTION_DATABASE_PERMISSIONS_ERROR = "CONNECTION_DATABASE_PERMISSIONS_ERROR"
      CONNECTION_MISSING_PARAMETERS_ERROR = "CONNECTION_MISSING_PARAMETERS_ERROR"
  
      # Viz errors
      VIZ_GET_DF_ERROR = "VIZ_GET_DF_ERROR"
      UNKNOWN_DATASOURCE_TYPE_ERROR = "UNKNOWN_DATASOURCE_TYPE_ERROR"
      FAILED_FETCHING_DATASOURCE_INFO_ERROR = "FAILED_FETCHING_DATASOURCE_INFO_ERROR"
  
      # Security access errors
      TABLE_SECURITY_ACCESS_ERROR = "TABLE_SECURITY_ACCESS_ERROR"
      DATASOURCE_SECURITY_ACCESS_ERROR = "DATASOURCE_SECURITY_ACCESS_ERROR"
      DATABASE_SECURITY_ACCESS_ERROR = "DATABASE_SECURITY_ACCESS_ERROR"
      MISSING_OWNERSHIP_ERROR = "MISSING_OWNERSHIP_ERROR"
  
      # Other errors
      BACKEND_TIMEOUT_ERROR = "BACKEND_TIMEOUT_ERROR"
  
      # Sql Lab errors
      MISSING_TEMPLATE_PARAMS_ERROR = "MISSING_TEMPLATE_PARAMS_ERROR"
  
      # Generic errors
      GENERIC_COMMAND_ERROR = "GENERIC_COMMAND_ERROR"
      GENERIC_BACKEND_ERROR = "GENERIC_BACKEND_ERROR"
  
      # API errors
      INVALID_PAYLOAD_FORMAT_ERROR = "INVALID_PAYLOAD_FORMAT_ERROR"
      INVALID_PAYLOAD_SCHEMA_ERROR = "INVALID_PAYLOAD_SCHEMA_ERROR"
  
  
  ERROR_TYPES_TO_ISSUE_CODES_MAPPING = {
      SupersetErrorType.BACKEND_TIMEOUT_ERROR: [
          {
              "code": 1000,
              "message": _("Issue 1000 - The datasource is too large to query."),
          },
          {
              "code": 1001,
              "message": _("Issue 1001 - The database is under an unusual load."),
          },
      ],
      SupersetErrorType.GENERIC_DB_ENGINE_ERROR: [
          {
              "code": 1002,
              "message": _("Issue 1002 - The database returned an unexpected error."),
          }
      ],
      SupersetErrorType.COLUMN_DOES_NOT_EXIST_ERROR: [
          {
              "code": 1003,
              "message": _(
                  "Issue 1003 - There is a syntax error in the SQL query. "
                  "Perhaps there was a misspelling or a typo."
              ),
          },
          {
              "code": 1004,
              "message": _(
                  "Issue 1004 - The column was deleted or renamed in the database."
              ),
          },
      ],
      SupersetErrorType.TABLE_DOES_NOT_EXIST_ERROR: [
          {
              "code": 1003,
              "message": _(
                  "Issue 1003 - There is a syntax error in the SQL query. "
                  "Perhaps there was a misspelling or a typo."
              ),
          },
          {
              "code": 1005,
              "message": _(
                  "Issue 1005 - The table was deleted or renamed in the database."
              ),
          },
      ],
      SupersetErrorType.SCHEMA_DOES_NOT_EXIST_ERROR: [
          {
              "code": 1003,
              "message": _(
                  "Issue 1003 - There is a syntax error in the SQL query. "
                  "Perhaps there was a misspelling or a typo."
              ),
          },
          {
              "code": 1016,
              "message": _(
                  "Issue 1005 - The schema was deleted or renamed in the database."
              ),
          },
      ],
      SupersetErrorType.MISSING_TEMPLATE_PARAMS_ERROR: [
          {
              "code": 1006,
              "message": _(
                  "Issue 1006 - One or more parameters specified in the query are "
                  "missing."
              ),
          },
      ],
      SupersetErrorType.CONNECTION_INVALID_HOSTNAME_ERROR: [
          {
              "code": 1007,
              "message": _("Issue 1007 - The hostname provided can't be resolved."),
          },
      ],
      SupersetErrorType.CONNECTION_PORT_CLOSED_ERROR: [
          {"code": 1008, "message": _("Issue 1008 - The port is closed.")},
      ],
      SupersetErrorType.CONNECTION_HOST_DOWN_ERROR: [
          {
              "code": 1009,
              "message": _(
                  "Issue 1009 - The host might be down, and can't be reached on the "
                  "provided port."
              ),
          },
      ],
      SupersetErrorType.GENERIC_COMMAND_ERROR: [
          {
              "code": 1010,
              "message": _(
                  "Issue 1010 - Superset encountered an error while running a command."
              ),
          },
      ],
      SupersetErrorType.GENERIC_BACKEND_ERROR: [
          {
              "code": 1011,
              "message": _("Issue 1011 - Superset encountered an unexpected error."),
          },
      ],
      SupersetErrorType.CONNECTION_INVALID_USERNAME_ERROR: [
          {
              "code": 1012,
              "message": _(
                  "Issue 1012 - The username provided when "
                  "connecting to a database is not valid."
              ),
          },
      ],
      SupersetErrorType.CONNECTION_INVALID_PASSWORD_ERROR: [
          {
              "code": 1013,
              "message": _(
                  "Issue 1013 - The password provided when "
                  "connecting to a database is not valid."
              ),
          },
      ],
      SupersetErrorType.CONNECTION_ACCESS_DENIED_ERROR: [
          {
              "code": 1014,
              "message": _("Issue 1014 - Either the username or the password is wrong."),
          },
          {
              "code": 1015,
              "message": _(
                  "Issue 1015 - Either the database is "
                  "spelled incorrectly or does not exist."
              ),
          },
      ],
      SupersetErrorType.CONNECTION_UNKNOWN_DATABASE_ERROR: [
          {
              "code": 1015,
              "message": _(
                  "Issue 1015 - Either the database is "
                  "spelled incorrectly or does not exist."
              ),
          }
      ],
      SupersetErrorType.CONNECTION_DATABASE_PERMISSIONS_ERROR: [
          {
              "code": 1017,
              "message": _("Issue 1017 - User doesn't have the proper permissions."),
          },
      ],
      SupersetErrorType.CONNECTION_MISSING_PARAMETERS_ERROR: [
          {
              "code": 1018,
              "message": _(
                  "Issue 1018 - One or more parameters needed to configure a "
                  "database are missing."
              ),
          },
      ],
      SupersetErrorType.INVALID_PAYLOAD_FORMAT_ERROR: [
          {
              "code": 1019,
              "message": _(
                  "Issue 1019 - The submitted payload has the incorrect format."
              ),
          }
      ],
      SupersetErrorType.INVALID_PAYLOAD_SCHEMA_ERROR: [
          {
              "code": 1020,
              "message": _(
                  "Issue 1020 - The submitted payload has the incorrect schema."
              ),
          }
      ],
  }
  
  
  class ErrorLevel(str, Enum):
      """
      Levels of errors that can exist within Superset.
  
      Keep in sync with superset-frontend/src/components/ErrorMessage/types.ts
      """
  
      INFO = "info"
      WARNING = "warning"
      ERROR = "error"
  
  
  @dataclass
  class SupersetError:
      """
      An error that is returned to a client.
      """
  
      message: str
      error_type: SupersetErrorType
      level: ErrorLevel
      extra: Optional[Dict[str, Any]] = None
  
      def __post_init__(self) -> None:
          """
          Mutates the extra params with user facing error codes that map to backend
          errors.
          """
          issue_codes = ERROR_TYPES_TO_ISSUE_CODES_MAPPING.get(self.error_type)
          if issue_codes:
              self.extra = self.extra or {}
              self.extra.update({"issue_codes": issue_codes})
  