Azure Databricks 中的错误处理

适用于:勾选“是” Databricks SQL 勾选“是” Databricks Runtime 12.2 及更高版本

错误组件

当 Azure Databricks 引发错误时,错误包括以下组件:

  • 错误类

    错误条件特有的用户可读的描述性字符串。

    某些错误类包括子类。

    例如:TABLE_OR_VIEW_NOT_FOUNDINCOMPLETE_TYPE_DEFINITION.ARRAY

    有关所有错误类的列表,请参阅错误类

  • SQLSTATE

    五个字符长的字符串,将错误类分组为许多产品和 API 支持的标准格式。

    例如:'42P01'

    有关 Azure Databricks 使用的所有 SQLSTATE 的完整列表,请参阅 SQLSTATE

  • 参数化的消息

    参数占位符的错误消息。

    例如:TABLE_OR_VIEW_NOT_FOUND 包含以下消息:

    The table or view <relationName> cannot be found.
    

    可以使用参数化的消息来呈现错误消息,方法是将消息参数值映射到参数标记 <parameter>

  • 消息参数

    提供有关错误的其他信息的参数和值的映射。 例如:'relationName' -> 'main.default.tab1'

  • 消息

    完全呈现的错误消息,包括错误类和 SQLSTATE,其中填入了参数。 例如:

    [TABLE_OR_VIEW_NOT_FOUND] The table or view `does_not_exist` cannot be found. Verify the spelling and correctness of the schema and catalog.
    If you did not qualify the name with a schema, verify the current_schema() output, or qualify the name with the correct schema and catalog.
    To tolerate the error on drop use DROP VIEW IF EXISTS or DROP TABLE IF EXISTS. SQLSTATE: 42P01; line 1 pos 14;
    'Project [*]
    +- 'UnresolvedRelation [does_not_exist], [], false
    

警告

“消息”和“参数化的消息”跨版本不稳定。 消息文本可能会更改或本地化,恕不另行通知。 若要以编程方式处理错误条件,请改用“错误类”、SQLSTATE 和“消息参数”

处理错误条件

适用于:勾选“是”Databricks SQL勾选“是”、Databricks Runtime 14.2 及更高版本

重要

此功能目前以公共预览版提供。

Azure Databricks 提供特定于语言的 API 来处理错误条件。

Python

对于 Python,请使用 pySparkException

  • PySparkException.getErrorClass():以字符串的形式返回异常的错误类。
  • PySparkException.getMessageParameters():以字典的形式返回异常的消息参数。
  • PySparkException.getSqlState():以字符串的形式返回表达式的 SQLSTATE

Scala

对于 Scala,请使用 SparkThrowable

  • getErrorClass():以字符串的形式返回错误类。
  • getMessageParameters():以映射的形式返回消息参数。
  • getSqlState():以字符串的形式返回 SQLSTATE。

示例

  • 捕获任何异常并显示错误类、消息参数和 SQLSTATE。 还显示默认错误消息

    Scala

    import org.apache.spark.SparkThrowable
    
    try {
      spark.sql("SELECT * FROM does_not_exist").show()
    }
    catch {
      case ex: SparkThrowable =>
        println("Error Class       : " + ex.getErrorClass)
        println("Message parameters: " + ex.getMessageParameters())
        println("SQLSTATE          : " + ex.getSqlState)
        println(ex)
    }
    

    Python

    from pyspark.errors import PySparkException
    
    try:
      spark.sql("SELECT * FROM does_not_exist").show()
    except PySparkException as ex:
      print("Error Class       : " + ex.getErrorClass())
      print("Message parameters: " + str(ex.getMessageParameters()))
      print("SQLSTATE          : " + ex.getSqlState())
      print(ex)
    

    结果

      Error Class       : TABLE_OR_VIEW_NOT_FOUND
      Message parameters: {'relationName': '`does_not_exist`'}
      SQLSTATE          : 42P01
      [TABLE_OR_VIEW_NOT_FOUND] The table or view `does_not_exist` cannot be found. Verify the spelling and correctness of the schema and catalog.
      If you did not qualify the name with a schema, verify the current_schema() output, or qualify the name with the correct schema and catalog.
      To tolerate the error on drop use DROP VIEW IF EXISTS or DROP TABLE IF EXISTS. SQLSTATE: 42P01; line 1 pos 14;
      'Project [*]
      +- 'UnresolvedRelation [does_not_exist], [], false
    
  • 仅捕获 SQLSTATE 42P01 并显示自定义消息:

    Scala

    import org.apache.spark.SparkThrowable
    
    try {
      spark.sql("SELECT * FROM does_not_exist").show()
    }
    catch {
      case ex: SparkThrowable if (ex.getSqlState == "42P01") =>
        println("I'm so sorry, but I cannot find: " + ex.getMessageParameters().get("relationName"))
    }
    

    Python

    from pyspark.errors import PySparkException
    
    try:
      spark.sql("SELECT * FROM does_not_exist").show()
    except PySparkException as ex:
      if (ex.getSqlState() == "42P01"):
        print("I'm so sorry, but I cannot find: " + ex.getMessageParameters()['relationName'])
      else:
        raise
    

    结果

    I'm so sorry, but I cannot find: `does_not_exist`
    
  • 仅捕获错误类 TABLE_OR_VIEW_NOT_FOUND 并显示自定义消息:

    Scala

    import org.apache.spark.SparkThrowable
    
    try {
      spark.sql("SELECT * FROM does_not_exist").show()
    }
    catch {
      case ex: SparkThrowable if (ex.getErrorClass == "TABLE_OR_VIEW_NOT_FOUND") =>
        println("I'm so sorry, but I cannot find: " + ex.getMessageParameters().get("relationName"))
    }
    

    Python

    from pyspark.errors import PySparkException
    
    try:
      spark.sql("SELECT * FROM does_not_exist").show()
    except PySparkException as ex:
      if (ex.getErrorClass() == "TABLE_OR_VIEW_NOT_FOUND"):
        print("I'm so sorry, but I cannot find: " + ex.getMessageParameters()['relationName'])
      else:
        raise
    

    结果

    I'm so sorry, but I cannot find: `does_not_exist`
    

用户引发的异常

Azure Databricks 提供以下函数来引发用户定义的错误:

  • raise_error

    引发带有自定义错误消息的异常。

  • assert_true

    如果未满足条件,则引发带有可选错误消息的错误。

这两个函数都会返回错误类“USER_RAISED_EXCEPTION”SQLSTATE 'P0001' 以及一条用户定义的消息。

示例

> SELECT raise_error('This is a custom error message');
 [USER_RAISED_EXCEPTION] This is a custom error message. SQLSTATE: P0001

> SELECT assert_true(1 = 2, 'One is not two!');
 [USER_RAISED_EXCEPTION] One is not two! SQLSTATE: P0001

> SELECT assert_true(1 = 2);
 [USER_RAISED_EXCEPTION] '(1 = 2)' is not true! SQLSTATE: P0001