-
Notifications
You must be signed in to change notification settings - Fork 35
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
Implementing error types #117
Changes from 4 commits
cb4b41d
aff1bc8
fb50b06
0cef7a7
c5b8e94
b8ad0d7
751ae8c
adc53f8
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 |
---|---|---|
|
@@ -13,7 +13,7 @@ import ( | |
"github.com/databricks/databricks-sql-go/internal/cli_service" | ||
"github.com/databricks/databricks-sql-go/internal/client" | ||
"github.com/databricks/databricks-sql-go/internal/config" | ||
dbsqlerr "github.com/databricks/databricks-sql-go/internal/err" | ||
dbsqlerr "github.com/databricks/databricks-sql-go/internal/errors" | ||
"github.com/databricks/databricks-sql-go/logger" | ||
) | ||
|
||
|
@@ -35,7 +35,7 @@ func (c *connector) Connect(ctx context.Context) (driver.Conn, error) { | |
|
||
tclient, err := client.InitThriftClient(c.cfg, c.client) | ||
if err != nil { | ||
return nil, dbsqlerr.WrapErr(err, "error initializing thrift client") | ||
return nil, dbsqlerr.NewRequestError(ctx, dbsqlerr.ErrThriftClient, err) | ||
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. driver error |
||
} | ||
protocolVersion := int64(c.cfg.ThriftProtocolVersion) | ||
session, err := tclient.OpenSession(ctx, &cli_service.TOpenSessionReq{ | ||
|
@@ -49,7 +49,7 @@ func (c *connector) Connect(ctx context.Context) (driver.Conn, error) { | |
}) | ||
|
||
if err != nil { | ||
return nil, dbsqlerr.WrapErrf(err, "error connecting: host=%s port=%d, httpPath=%s", c.cfg.Host, c.cfg.Port, c.cfg.HTTPPath) | ||
return nil, dbsqlerr.NewRequestError(ctx, fmt.Sprintf("error connecting: host=%s port=%d, httpPath=%s", c.cfg.Host, c.cfg.Port, c.cfg.HTTPPath), err) | ||
} | ||
|
||
conn := &conn{ | ||
|
@@ -66,7 +66,7 @@ func (c *connector) Connect(ctx context.Context) (driver.Conn, error) { | |
setStmt := fmt.Sprintf("SET `%s` = `%s`;", k, v) | ||
_, err := conn.ExecContext(ctx, setStmt, []driver.NamedValue{}) | ||
if err != nil { | ||
return nil, err | ||
return nil, dbsqlerr.NewExecutionError(ctx, fmt.Sprintf("error setting session param: %s", setStmt), err, nil) | ||
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. this should be just returning the error, no? |
||
} | ||
log.Info().Msgf("set session parameter: param=%s value=%s", k, v) | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -144,6 +144,52 @@ The result log may look like this: | |
|
||
{"level":"debug","connId":"01ed6545-5669-1ec7-8c7e-6d8a1ea0ab16","corrId":"workflow-example","queryId":"01ed6545-57cc-188a-bfc5-d9c0eaf8e189","time":1668558402,"message":"Run Main elapsed time: 1.298712292s"} | ||
|
||
# Errors | ||
|
||
There are three error types exposed via dbsql/errors | ||
|
||
DBSystemFault - A fault caused by Databricks services | ||
|
||
DBRequestError - An error that is caused by an invalid request. Example: permission denied, or the user tries to access a warehouse that doesn’t exist | ||
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. some more examples would really help |
||
|
||
DBExecutionError - Any error that occurs after the SQL statement has been accepted (e.g. SQL syntax error) | ||
|
||
Each type has a corresponding sentinel value which can be used with errors.Is() to determine if one of the types is present in an error chain. | ||
|
||
SystemFault | ||
RequestError | ||
ExecutionError | ||
|
||
Example usage: | ||
|
||
import ( | ||
fmt | ||
errors | ||
dbsqlerr "github.com/databricks/databricks-sql-go/errors" | ||
) | ||
|
||
func main() { | ||
... | ||
_, err := db.ExecContext(ogCtx, `Select id from range(100)`) | ||
if err != nil { | ||
if errors.Is(err, dbsqlerr.ExecutionError) { | ||
var execErr dbsqlerr.DBExecutionError | ||
if ok := errors.As(err, &execError); ok { | ||
fmt.Printf("%s, corrId: %s, connId: %s, queryId: %s, sqlState: %s", | ||
execErr.Error(), | ||
execErr.CorrelationId(), | ||
execErr.ConnectionId(), | ||
execErr.QueryId(), | ||
execErr.SqlState()) | ||
} | ||
} | ||
... | ||
} | ||
... | ||
} | ||
|
||
See the documentation for dbsql/errors for more information. | ||
|
||
# Supported Data Types | ||
|
||
================================== | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package errors | ||
|
||
import "github.com/pkg/errors" | ||
|
||
// value to be used with errors.Is() to determine if an error chain contains a request error | ||
var RequestError error = errors.New("Request Error") | ||
|
||
// value to be used with errors.Is() to determine if an error chain contains a system fault | ||
var SystemFault error = errors.New("System Fault") | ||
|
||
// value to be used with errors.Is() to determine if an error chain contains an execution error | ||
var ExecutionError error = errors.New("Execution Error") | ||
|
||
// Base interface for driver errors | ||
type DatabricksError interface { | ||
// Descriptive message describing the error | ||
Error() string | ||
|
||
// ErrorType() DBsqlErrorType | ||
|
||
// User specified id to track what happens under a request. Useful to track multiple connections in the same request. | ||
// Appears in log messages as field corrId. See driverctx.NewContextWithCorrelationId() | ||
CorrelationId() string | ||
|
||
// Internal id to track what happens under a connection. Connections can be reused so this would track across queries. | ||
// Appears in log messages as field connId. | ||
ConnectionId() string | ||
|
||
// Stack trace associated with the error. May be nil. | ||
StackTrace() errors.StackTrace | ||
|
||
// Underlying causative error. May be nil. | ||
Cause() error | ||
} | ||
|
||
// An error that is caused by an invalid request. | ||
// Example: permission denied, or the user tries to access a warehouse that doesn’t exist | ||
type DBRequestError interface { | ||
DatabricksError | ||
} | ||
|
||
// A fault that is caused by Databricks services | ||
type DBSystemFault interface { | ||
DatabricksError | ||
|
||
IsRetryable() bool | ||
} | ||
|
||
// Any error that occurs after the SQL statement has been accepted (e.g. SQL syntax error). | ||
type DBExecutionError interface { | ||
DatabricksError | ||
|
||
// Internal id to track what happens under a query. | ||
// Appears in log messages as field queryId. | ||
QueryId() string | ||
|
||
// Optional portable error identifier across SQL engines. | ||
// See https://github.com/apache/spark/tree/master/core/src/main/resources/error#ansiiso-standard | ||
SqlState() string | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
request error?