@@ -279,6 +279,15 @@ func SprintGuid(bts []byte) string {
279279
280280var retryableStatusCode = []int {http .StatusTooManyRequests , http .StatusServiceUnavailable }
281281
282+ func isRetryable (statusCode int ) bool {
283+ for _ , c := range retryableStatusCode {
284+ if c == statusCode {
285+ return true
286+ }
287+ }
288+ return false
289+ }
290+
282291type Transport struct {
283292 Base * http.Transport
284293 Authr auth.Authenticator
@@ -321,14 +330,13 @@ func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
321330 if resp .StatusCode != http .StatusOK {
322331 reason := resp .Header .Get ("X-Databricks-Reason-Phrase" )
323332 terrmsg := resp .Header .Get ("X-Thriftserver-Error-Message" )
324- for _ , c := range retryableStatusCode {
325- if c == resp .StatusCode {
326- if terrmsg != "" {
327- logger .Warn ().Msg (terrmsg )
328- }
329- return resp , nil
333+ if isRetryable (resp .StatusCode ) {
334+ if terrmsg != "" {
335+ logger .Warn ().Msg (terrmsg )
330336 }
337+ return resp , nil
331338 }
339+
332340 if reason != "" {
333341 logger .Err (fmt .Errorf (reason )).Msg ("non retryable error" )
334342 return nil , errors .New (reason )
@@ -426,17 +434,25 @@ func errorHandler(resp *http.Response, err error, numTries int) (*http.Response,
426434 if err == nil {
427435 err = errors .New (fmt .Sprintf ("request error after %d attempt(s)" , numTries ))
428436 }
429- if resp != nil && resp .Header != nil {
430437
438+ if resp != nil {
439+ var orgid , reason , terrmsg , errmsg , retryAfter string
431440 // TODO @mattdeekay: convert these to specific error types
441+ if resp .Header != nil {
442+ orgid = resp .Header .Get ("X-Databricks-Org-Id" )
443+ reason = resp .Header .Get ("X-Databricks-Reason-Phrase" ) // TODO note: shown on notebook
444+ terrmsg = resp .Header .Get ("X-Thriftserver-Error-Message" )
445+ errmsg = resp .Header .Get ("x-databricks-error-or-redirect-message" )
446+ retryAfter = resp .Header .Get ("Retry-After" )
447+ // TODO note: need to see if there's other headers
448+ }
449+ msg := fmt .Sprintf ("orgId: %s, reason: %s, thriftErr: %s, err: %s" , orgid , reason , terrmsg , errmsg )
432450
433- orgid := resp .Header .Get ("X-Databricks-Org-Id" )
434- reason := resp .Header .Get ("X-Databricks-Reason-Phrase" ) // TODO note: shown on notebook
435- terrmsg := resp .Header .Get ("X-Thriftserver-Error-Message" )
436- errmsg := resp .Header .Get ("x-databricks-error-or-redirect-message" )
437- // TODO note: need to see if there's other headers
451+ if isRetryable (resp .StatusCode ) {
452+ err = dbsqlerrint .NewRetryableError (err , retryAfter )
453+ }
438454
439- werr = errors . Wrapf (err , fmt . Sprintf ( "orgId: %s, reason: %s, thriftErr: %s, err: %s" , orgid , reason , terrmsg , errmsg ) )
455+ werr = dbsqlerrint . WrapErr (err , msg )
440456 } else {
441457 werr = err
442458 }
@@ -464,11 +480,8 @@ func RetryPolicy(ctx context.Context, resp *http.Response, err error) (bool, err
464480 // 429 Too Many Requests or 503 service unavailable is recoverable. Sometimes the server puts
465481 // a Retry-After response header to indicate when the server is
466482 // available to start processing request from client.
467-
468- for _ , c := range retryableStatusCode {
469- if c == resp .StatusCode {
470- return true , nil
471- }
483+ if isRetryable (resp .StatusCode ) {
484+ return true , nil
472485 }
473486
474487 return false , nil
0 commit comments