temporal有一套自己的错误机制,对于workflow和activity方法来说,错误返回都会被temporal层层封装,最后在外部拿到的是一个temporal类型的错误码
对于workflow或者activity方法的错误返回,我们收到的一般都是类似这种信息:
Activity error. Namespace default TaskQueue ting-queue-20130815 WorkerID 1@ting-temporal-worker-769645ffc5-r4489@ WorkflowID 1825b61a-d237-40e8-95e3-a8459fde36ee_11 RunID 2d57479c-abf7-41ae-b661-94f557617846 ActivityType RunOnCheckCancelTaskActivity Attempt 1 Error task canceled
这导致有时候我们想通过返回自定义错误,然后在外部进行错误类型判断的时候取不到的问题。
自定义错误与解包
其实框架提供了机制进行错误的解封装,参考如下:
// TaskTimeoutErr 任务超时
type TaskTimeoutErr struct {
Msg string
}
func (tt *TaskTimeoutErr) Error() string {
return tt.Msg
}
func NewTaskTimeoutErr(msg string) *TaskTimeoutErr {
return &TaskTimeoutErr{msg}
}
// TaskCancelErr 任务取消
type TaskCancelErr struct {
Msg string
}
func (tc *TaskCancelErr) Error() string {
return tc.Msg
}
func NewTaskCancelErr(msg string) *TaskCancelErr {
return &TaskCancelErr{msg}
}
// TaskSkipErr 任务跳过
type TaskSkipErr struct {
Msg string
}
func (ts *TaskSkipErr) Error() string {
return ts.Msg
}
func NewTaskSkipErr(msg string) *TaskSkipErr {
return &TaskSkipErr{msg}
}
func Unwrap(err error) error {
if temporal.IsCanceledError(err) {
return TaskCancel
}
var applicationErr *temporal.ApplicationError
if errors.As(err, &applicationErr) {
log.Debugf("application err, type: %s", applicationErr.Type())
switch applicationErr.Type() {
case "TaskTimeoutErr":
return TaskTimeout
case "TaskCancelErr":
return TaskCancel
case "TaskSkipErr":
return TaskSkip
}
}
var panicErr *temporal.PanicError
if errors.As(err, &panicErr) {
log.Errorf("panic err: %+v", panicErr.StackTrace())
}
return err
}
错误重试控制
我们还可以通过自定义错误码来控制temporal 的重试,比如有些错误我们是不需要重试的,那么就可以:
var retryPolicy = &temporal.RetryPolicy{
InitialInterval: time.Second,
BackoffCoefficient: 2,
MaximumInterval: time.Minute * 1,
MaximumAttempts: 100,
NonRetryableErrorTypes: []string{
"TaskTimeoutErr",
"TaskCancelErr",
"TaskSkipErr",
"TaskFailErr",
"TaskFinishedCancelErr",
"PanicError",
"TerminatedError",
},
}
var ActivityOpts = workflow.ActivityOptions{
StartToCloseTimeout: 168 * time.Hour,
HeartbeatTimeout: 60 * time.Second,
RetryPolicy: retryPolicy,
WaitForCancellation: true,
}
https://legacy-documentation-sdks.temporal.io/go/error-handling