-
Notifications
You must be signed in to change notification settings - Fork 29k
[SPARK-45516][CONNECT] Include QueryContext in SparkThrowable proto message #43352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -115,6 +115,17 @@ private[connect] object ErrorUtils extends Logging { | |
| if (sparkThrowable.getErrorClass != null) { | ||
| sparkThrowableBuilder.setErrorClass(sparkThrowable.getErrorClass) | ||
| } | ||
| for (queryCtx <- sparkThrowable.getQueryContext) { | ||
| sparkThrowableBuilder.addQueryContexts( | ||
| FetchErrorDetailsResponse.QueryContext | ||
| .newBuilder() | ||
| .setObjectType(queryCtx.objectType()) | ||
| .setObjectName(queryCtx.objectName()) | ||
| .setStartIndex(queryCtx.startIndex()) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, this should actually fail after #43334 PR because Seems like we miss this information Spark Connect client sides for now so it seems working .. but we should carry this context for DataFrame operations ..
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @MaxGekk I think there's a bug not only here but without Spark Connect. scala> try {
| spark.range(1).select("a")
| } catch {
| case e: org.apache.spark.sql.catalyst.ExtendedAnalysisException => println(e.getQueryContext)
| }
[Lorg.apache.spark.QueryContext;@6a9d7514
val res2: Any = ()It doesn't contain
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright, there are three issues. TL;DR:
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
do you mean client? Server side stacktrace is not interesting to users to understand their own code mistakes.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made a mistake. I updated my comment.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Either setting a default value or making the protobuf field optional should work. It depends on the semantic of cc: @MaxGekk
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's make sure we fix this. |
||
| .setStopIndex(queryCtx.stopIndex()) | ||
| .setFragment(queryCtx.fragment()) | ||
| .build()) | ||
| } | ||
| sparkThrowableBuilder.putAllMessageParameters(sparkThrowable.getMessageParameters) | ||
| builder.setSparkThrowable(sparkThrowableBuilder.build()) | ||
| case _ => | ||
|
|
||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2869,6 +2869,59 @@ class FetchErrorDetailsResponse(google.protobuf.message.Message): | |
| self, oneof_group: typing_extensions.Literal["_file_name", b"_file_name"] | ||
| ) -> typing_extensions.Literal["file_name"] | None: ... | ||
|
|
||
| class QueryContext(google.protobuf.message.Message): | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. qq; could we do this in Python client too?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not yet if I understand correctly. @gatorsmile has some concern about whether exposing QueryContext in the PySpark Exception APIs makes sense for non-sql PySpark exceptions. There is some ongoing discussion for this. |
||
| """QueryContext defines the schema for the query context of a SparkThrowable. | ||
| It helps users understand where error occur while executing queries. | ||
| """ | ||
|
|
||
| DESCRIPTOR: google.protobuf.descriptor.Descriptor | ||
|
|
||
| OBJECT_TYPE_FIELD_NUMBER: builtins.int | ||
| OBJECT_NAME_FIELD_NUMBER: builtins.int | ||
| START_INDEX_FIELD_NUMBER: builtins.int | ||
| STOP_INDEX_FIELD_NUMBER: builtins.int | ||
| FRAGMENT_FIELD_NUMBER: builtins.int | ||
| object_type: builtins.str | ||
| """The object type of the query which throws the exception. | ||
| If the exception is directly from the main query, it should be an empty string. | ||
| Otherwise, it should be the exact object type in upper case. For example, a "VIEW". | ||
| """ | ||
| object_name: builtins.str | ||
| """The object name of the query which throws the exception. | ||
| If the exception is directly from the main query, it should be an empty string. | ||
| Otherwise, it should be the object name. For example, a view name "V1". | ||
| """ | ||
| start_index: builtins.int | ||
| """The starting index in the query text which throws the exception. The index starts from 0.""" | ||
| stop_index: builtins.int | ||
| """The stopping index in the query which throws the exception. The index starts from 0.""" | ||
| fragment: builtins.str | ||
| """The corresponding fragment of the query which throws the exception.""" | ||
| def __init__( | ||
| self, | ||
| *, | ||
| object_type: builtins.str = ..., | ||
| object_name: builtins.str = ..., | ||
| start_index: builtins.int = ..., | ||
| stop_index: builtins.int = ..., | ||
| fragment: builtins.str = ..., | ||
| ) -> None: ... | ||
| def ClearField( | ||
| self, | ||
| field_name: typing_extensions.Literal[ | ||
| "fragment", | ||
| b"fragment", | ||
| "object_name", | ||
| b"object_name", | ||
| "object_type", | ||
| b"object_type", | ||
| "start_index", | ||
| b"start_index", | ||
| "stop_index", | ||
| b"stop_index", | ||
| ], | ||
| ) -> None: ... | ||
|
|
||
| class SparkThrowable(google.protobuf.message.Message): | ||
| """SparkThrowable defines the schema for SparkThrowable exceptions.""" | ||
|
|
||
|
|
@@ -2893,18 +2946,30 @@ class FetchErrorDetailsResponse(google.protobuf.message.Message): | |
|
|
||
| ERROR_CLASS_FIELD_NUMBER: builtins.int | ||
| MESSAGE_PARAMETERS_FIELD_NUMBER: builtins.int | ||
| QUERY_CONTEXTS_FIELD_NUMBER: builtins.int | ||
| error_class: builtins.str | ||
| """Succinct, human-readable, unique, and consistent representation of the error category.""" | ||
| @property | ||
| def message_parameters( | ||
| self, | ||
| ) -> google.protobuf.internal.containers.ScalarMap[builtins.str, builtins.str]: | ||
| """message parameters for the error framework.""" | ||
| """The message parameters for the error framework.""" | ||
| @property | ||
| def query_contexts( | ||
| self, | ||
| ) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[ | ||
| global___FetchErrorDetailsResponse.QueryContext | ||
| ]: | ||
| """The query context of a SparkThrowable""" | ||
| def __init__( | ||
| self, | ||
| *, | ||
| error_class: builtins.str | None = ..., | ||
| message_parameters: collections.abc.Mapping[builtins.str, builtins.str] | None = ..., | ||
| query_contexts: collections.abc.Iterable[ | ||
| global___FetchErrorDetailsResponse.QueryContext | ||
| ] | ||
| | None = ..., | ||
| ) -> None: ... | ||
| def HasField( | ||
| self, | ||
|
|
@@ -2921,6 +2986,8 @@ class FetchErrorDetailsResponse(google.protobuf.message.Message): | |
| b"error_class", | ||
| "message_parameters", | ||
| b"message_parameters", | ||
| "query_contexts", | ||
| b"query_contexts", | ||
| ], | ||
| ) -> None: ... | ||
| def WhichOneof( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.