This is an automated email from the ASF dual-hosted git repository.
mgrund pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/spark-connect-go.git
The following commit(s) were added to refs/heads/master by this push:
new 361a564 [#63] Add stack trace support to spark errors
361a564 is described below
commit 361a5643608c614425296fea91fc1f72d918d125
Author: Mathias Schwarz <[email protected]>
AuthorDate: Wed Aug 28 16:47:20 2024 +0200
[#63] Add stack trace support to spark errors
### What changes were proposed in this pull request?
Adding stack trace support to spark errors via the commonly used
"github.com/go-errors/errors" library
https://github.com/apache/spark-connect-go/issues/63
### Why are the changes needed?
Increased debugability
### Does this PR introduce _any_ user-facing change?
No
### How was this patch tested?
Unit test added
Closes #64 from mathiasschw-db/mathiasschw-db/stack_tract_support.
Authored-by: Mathias Schwarz
<[email protected]>
Signed-off-by: Martin Grund <[email protected]>
---
go.mod | 1 +
go.sum | 2 ++
spark/sparkerrors/errors.go | 29 ++++++++++++++++++++++++-----
spark/sparkerrors/errors_test.go | 8 ++++++++
4 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/go.mod b/go.mod
index b2bbc14..5af2c7d 100644
--- a/go.mod
+++ b/go.mod
@@ -30,6 +30,7 @@ require (
require (
cloud.google.com/go/compute/metadata v0.4.0 // indirect
+ github.com/go-errors/errors v1.5.1 // indirect
github.com/kr/pretty v0.3.0 // indirect
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
golang.org/x/sync v0.7.0 // indirect
diff --git a/go.sum b/go.sum
index 4ab3290..a584e12 100644
--- a/go.sum
+++ b/go.sum
@@ -5,6 +5,8 @@ github.com/apache/arrow/go/v17 v17.0.0/go.mod
h1:jR7QHkODl15PfYyjM2nU+yTLScZ/qfj
github.com/creack/pty v1.1.9/go.mod
h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.1
h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/go-errors/errors v1.5.1
h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk=
+github.com/go-errors/errors v1.5.1/go.mod
h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/goccy/go-json v0.10.3
h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA=
github.com/goccy/go-json v0.10.3/go.mod
h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/google/flatbuffers v24.3.25+incompatible
h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI=
diff --git a/spark/sparkerrors/errors.go b/spark/sparkerrors/errors.go
index 75c693d..c2665c8 100644
--- a/spark/sparkerrors/errors.go
+++ b/spark/sparkerrors/errors.go
@@ -18,9 +18,10 @@ package sparkerrors
import (
"encoding/json"
- "errors"
"fmt"
+ "io"
+ "github.com/go-errors/errors"
"google.golang.org/genproto/googleapis/rpc/errdetails"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -28,7 +29,7 @@ import (
type wrappedError struct {
errorType error
- cause error
+ cause *errors.Error
}
func (w *wrappedError) Unwrap() []error {
@@ -36,16 +37,16 @@ func (w *wrappedError) Unwrap() []error {
}
func (w *wrappedError) Error() string {
- return fmt.Sprintf("%s: %s", w.errorType, w.cause)
+ return fmt.Sprintf("%s", w)
}
// WithType wraps an error with a type that can later be checked using
`errors.Is`
func WithType(err error, errType errorType) error {
- return &wrappedError{cause: err, errorType: errType}
+ return &wrappedError{cause: errors.Wrap(err, 1), errorType: errType}
}
func WithString(err error, errMsg string) error {
- return &wrappedError{cause: err, errorType: errors.New(errMsg)}
+ return &wrappedError{cause: errors.Wrap(err, 1), errorType:
errors.New(errMsg)}
}
type errorType error
@@ -61,6 +62,24 @@ var (
TestSetupError = errorType(errors.New("test setup
error"))
)
+// Format formats the error, supporting both short forms (v, s, q) and verbose
form (+v)
+func (w *wrappedError) Format(s fmt.State, verb rune) {
+ switch verb {
+ case 'v':
+ if s.Flag('+') {
+ _, _ = io.WriteString(s, "[sparkerror] ")
+ _, _ = io.WriteString(s, fmt.Sprintf("Error Type:
%s\n", w.errorType.Error()))
+ _, _ = io.WriteString(s, fmt.Sprintf("Error Cause:
%s\n%s", w.cause.Err.Error(), w.cause.Stack()))
+ return
+ }
+ fallthrough
+ case 's':
+ _, _ = io.WriteString(s, fmt.Sprintf("%s: %s", w.errorType,
w.cause))
+ case 'q':
+ _, _ = fmt.Fprintf(s, "%q", w.errorType.Error())
+ }
+}
+
type UnsupportedResponseTypeError struct {
ResponseType interface{}
}
diff --git a/spark/sparkerrors/errors_test.go b/spark/sparkerrors/errors_test.go
index 184ec97..0e867aa 100644
--- a/spark/sparkerrors/errors_test.go
+++ b/spark/sparkerrors/errors_test.go
@@ -16,6 +16,7 @@
package sparkerrors
import (
+ "fmt"
"testing"
"google.golang.org/genproto/googleapis/rpc/errdetails"
@@ -49,6 +50,13 @@ func TestNonGRPCErrorsAreConvertedAsWell(t *testing.T) {
assert.Equal(t, se.Message, assert.AnError.Error())
}
+func TestStackTracePrint(t *testing.T) {
+ err := WithType(assert.AnError, ConnectionError)
+ errorString := fmt.Sprintf("%+v", err)
+ t.Log(errorString)
+ assert.Contains(t, errorString,
"spark-connect-go/spark/sparkerrors/errors_test.go")
+}
+
func TestErrorDetailsExtractionFromGRPCStatus(t *testing.T) {
status := status.New(codes.Internal, "AnalysisException")
status, _ = status.WithDetails(&errdetails.ErrorInfo{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]