Skip to content

Commit

Permalink
Use Failure and FailureInfo for errors (#138)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexshtin committed May 26, 2020
1 parent 72a16b6 commit a88dec5
Show file tree
Hide file tree
Showing 29 changed files with 1,335 additions and 636 deletions.
2 changes: 1 addition & 1 deletion client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ type (
// To complete with a result.
// CompleteActivity(token, "Done", nil)
// To fail the activity with an error.
// CompleteActivity(token, nil, temporal.NewCustomError("reason", details)
// CompleteActivity(token, nil, temporal.NewApplicationError("reason", details)
// The activity can fail with below errors ErrorWithDetails, TimeoutError, CanceledError.
CompleteActivity(ctx context.Context, taskToken []byte, result interface{}, err error) error

Expand Down
56 changes: 32 additions & 24 deletions error.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,41 @@
package temporal

import (
"errors"

"go.temporal.io/temporal-proto/serviceerror"

"go.temporal.io/temporal/internal"
"go.temporal.io/temporal/workflow"
)

type (
// CustomError returned from workflow and activity implementations with reason and optional details.
CustomError = internal.CustomError
// ApplicationError returned from activity implementations with message and optional details.
ApplicationError = internal.ApplicationError

// CanceledError returned when operation was canceled.
CanceledError = internal.CanceledError

// ActivityTaskError returned from workflow when activity returned an error.
ActivityTaskError = internal.ActivityTaskError

// ServerError can be returned from server.
ServerError = internal.ServerError

// ChildWorkflowExecutionError returned from workflow when child workflow returned an error.
ChildWorkflowExecutionError = internal.ChildWorkflowExecutionError

// WorkflowExecutionError returned from workflow.
WorkflowExecutionError = internal.WorkflowExecutionError
)

// ErrNoData is returned when trying to extract strong typed data while there is no data available.
var ErrNoData = internal.ErrNoData

// NewCustomError create new instance of *CustomError with reason and optional details.
// Use CustomError for any use case specific errors that cross activity and child workflow boundaries.
func NewCustomError(reason string, details ...interface{}) *CustomError {
return internal.NewCustomError(reason, details...)
// NewApplicationError create new instance of *ApplicationError with reason and optional details.
// Use ApplicationError for any use case specific errors that cross activity and child workflow boundaries.
func NewApplicationError(reason string, nonRetryable bool, details ...interface{}) *ApplicationError {
return internal.NewApplicationError(reason, nonRetryable, details...)
}

// NewCanceledError creates CanceledError instance.
Expand All @@ -54,10 +68,10 @@ func NewCanceledError(details ...interface{}) *CanceledError {
return internal.NewCanceledError(details...)
}

// IsCustomError return if the err is a CustomError
func IsCustomError(err error) bool {
_, ok := err.(*CustomError)
return ok
// IsApplicationError return if the err is a ApplicationError
func IsApplicationError(err error) bool {
var applicationError *ApplicationError
return errors.As(err, &applicationError)
}

// IsWorkflowExecutionAlreadyStartedError return if the err is a WorkflowExecutionAlreadyStartedError
Expand All @@ -68,30 +82,24 @@ func IsWorkflowExecutionAlreadyStartedError(err error) bool {

// IsCanceledError return if the err is a CanceledError
func IsCanceledError(err error) bool {
_, ok := err.(*CanceledError)
return ok
}

// IsGenericError return if the err is a GenericError
func IsGenericError(err error) bool {
_, ok := err.(*workflow.GenericError)
return ok
var cancelError *CanceledError
return errors.As(err, &cancelError)
}

// IsTimeoutError return if the err is a TimeoutError
func IsTimeoutError(err error) bool {
_, ok := err.(*workflow.TimeoutError)
return ok
var timeoutError *workflow.TimeoutError
return errors.As(err, &timeoutError)
}

// IsTerminatedError return if the err is a TerminatedError
func IsTerminatedError(err error) bool {
_, ok := err.(*workflow.TerminatedError)
return ok
var terminateError *workflow.TerminatedError
return errors.As(err, &terminateError)
}

// IsPanicError return if the err is a PanicError
func IsPanicError(err error) bool {
_, ok := err.(*workflow.PanicError)
return ok
var panicError *workflow.PanicError
return errors.As(err, &panicError)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/uber-go/tally v3.3.16+incompatible
github.com/uber/jaeger-client-go v2.22.1+incompatible
github.com/uber/jaeger-lib v2.2.0+incompatible // indirect
go.temporal.io/temporal-proto v0.23.1
go.temporal.io/temporal-proto v0.23.2
go.uber.org/atomic v1.6.0
go.uber.org/goleak v1.0.0
go.uber.org/zap v1.15.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ github.com/uber/jaeger-client-go v2.22.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMW
github.com/uber/jaeger-lib v2.2.0+incompatible h1:MxZXOiR2JuoANZ3J6DE/U0kSFv/eJ/GfSYVCjK7dyaw=
github.com/uber/jaeger-lib v2.2.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.temporal.io/temporal-proto v0.23.1 h1:385YR4MXo0lK+J+8ublQY3uJaaf997ZqUaopSp1/9zs=
go.temporal.io/temporal-proto v0.23.1/go.mod h1:AUs3JCVjCSx2J2hpgkWlrVUt7R7obpONi1rDhAcV/Os=
go.temporal.io/temporal-proto v0.23.2 h1:8syxfKU0/g7DPb9sUHPvirVQ0zYi3rtvuTYtMY4qKas=
go.temporal.io/temporal-proto v0.23.2/go.mod h1:AUs3JCVjCSx2J2hpgkWlrVUt7R7obpONi1rDhAcV/Os=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/goleak v1.0.0 h1:qsup4IcBdlmsnGfqyLl4Ntn3C2XCCuKAE7DwHpScyUo=
Expand Down
14 changes: 6 additions & 8 deletions internal/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ type (
// To complete with a result.
// CompleteActivity(token, "Done", nil)
// To fail the activity with an error.
// CompleteActivity(token, nil, temporal.NewCustomError("reason", details)
// CompleteActivity(token, nil, temporal.NewApplicationError("reason", details)
// The activity can fail with below errors ErrorWithDetails, TimeoutError, CanceledError.
CompleteActivity(ctx context.Context, taskToken []byte, result interface{}, err error) error

Expand Down Expand Up @@ -477,13 +477,11 @@ type (
// If not set or set to 0, it means unlimited, and rely on activity ScheduleToCloseTimeout to stop.
MaximumAttempts int32

// Non-Retriable errors. This is optional. Temporal server will stop retry if error reason matches this list.
// Error reason for custom error is specified when your activity/workflow return temporal.NewCustomError(reason).
// Error reason for panic error is "temporalInternal:Panic".
// Error reason for any other error is "temporalInternal:Generic".
// Error reason for timeouts is: "temporalInternal:Timeout TIMEOUT_TYPE". TIMEOUT_TYPE could be TimeoutTypeStartToClose or TimeoutTypeHeartbeat.
// Note, cancellation is not a failure, so it won't be retried.
NonRetriableErrorReasons []string
// Non-Retriable errors. This is optional. Temporal server will stop retry if error type matches this list.
// Note:
// - cancellation is not a failure, so it won't be retried,
// - only StartToClose or Heartbeat timeouts are retryable.
NonRetryableErrorTypes []string
}

// NamespaceClient is the client for managing operations on the namespace.
Expand Down
2 changes: 1 addition & 1 deletion internal/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ var ErrCanceled = NewCanceledError()

// ErrDeadlineExceeded is the error returned by Context.Err when the context's
// deadline passes.
var ErrDeadlineExceeded = NewTimeoutError(commonpb.TimeoutType_ScheduleToClose)
var ErrDeadlineExceeded = NewTimeoutError(commonpb.TimeoutType_ScheduleToClose, nil)

// A CancelFunc tells an operation to abandon its work.
// A CancelFunc does not wait for the work to stop.
Expand Down
Loading

0 comments on commit a88dec5

Please sign in to comment.