@@ -26,6 +26,7 @@ import (
2626 "strings"
2727
2828 "go.uber.org/cadence/.gen/go/shared"
29+ "go.uber.org/cadence/encoded"
2930)
3031
3132/*
8788 // CustomError returned from workflow and activity implementations with reason and optional details.
8889 CustomError struct {
8990 reason string
90- details EncodedValues
91+ details encoded. Values
9192 }
9293
9394 // GenericError returned from workflow/workflow when the implementations return errors other than from NewCustomError() API.
@@ -98,12 +99,12 @@ type (
9899 // TimeoutError returned when activity or child workflow timed out.
99100 TimeoutError struct {
100101 timeoutType shared.TimeoutType
101- details EncodedValues
102+ details encoded. Values
102103 }
103104
104105 // CanceledError returned when operation was canceled.
105106 CanceledError struct {
106- details EncodedValues
107+ details encoded. Values
107108 }
108109
109110 // TerminatedError returned when workflow was terminated.
@@ -134,6 +135,9 @@ const (
134135// ErrNoData is returned when trying to extract strong typed data while there is no data available.
135136var ErrNoData = errors .New ("no data available" )
136137
138+ // ErrTooManyArg is returned when trying to extract strong typed data with more arguments than available data.
139+ var ErrTooManyArg = errors .New ("too many arguments" )
140+
137141// ErrActivityResultPending is returned from activity's implementation to indicate the activity is not completed when
138142// activity method returns. Activity needs to be completed by Client.CompleteActivity() separately. For example, if an
139143// activity require human interaction (like approve an expense report), the activity could return activity.ErrResultPending
@@ -146,12 +150,14 @@ func NewCustomError(reason string, details ...interface{}) *CustomError {
146150 if strings .HasPrefix (reason , "cadenceInternal:" ) {
147151 panic ("'cadenceInternal:' is reserved prefix, please use different reason" )
148152 }
149-
150- data , err := getHostEnvironment ().encodeArgs (details )
151- if err != nil {
152- panic (err )
153+ // When return error to user, use EncodedValues as details and data is ready to be decoded by calling Get
154+ if len (details ) == 1 {
155+ if d , ok := details [0 ].(* EncodedValues ); ok {
156+ return & CustomError {reason : reason , details : d }
157+ }
153158 }
154- return & CustomError {reason : reason , details : data }
159+ // When create error for server, use ErrorDetailsValues as details to hold values and encode later
160+ return & CustomError {reason : reason , details : ErrorDetailsValues (details )}
155161}
156162
157163// NewTimeoutError creates TimeoutError instance.
@@ -162,20 +168,22 @@ func NewTimeoutError(timeoutType shared.TimeoutType) *TimeoutError {
162168
163169// NewHeartbeatTimeoutError creates TimeoutError instance
164170func NewHeartbeatTimeoutError (details ... interface {}) * TimeoutError {
165- data , err := getHostEnvironment ().encodeArgs (details )
166- if err != nil {
167- panic (err )
171+ if len (details ) == 1 {
172+ if d , ok := details [0 ].(* EncodedValues ); ok {
173+ return & TimeoutError {timeoutType : shared .TimeoutTypeHeartbeat , details : d }
174+ }
168175 }
169- return & TimeoutError {timeoutType : shared .TimeoutTypeHeartbeat , details : data }
176+ return & TimeoutError {timeoutType : shared .TimeoutTypeHeartbeat , details : ErrorDetailsValues ( details ) }
170177}
171178
172179// NewCanceledError creates CanceledError instance
173180func NewCanceledError (details ... interface {}) * CanceledError {
174- data , err := getHostEnvironment ().encodeArgs (details )
175- if err != nil {
176- panic (err )
181+ if len (details ) == 1 {
182+ if d , ok := details [0 ].(* EncodedValues ); ok {
183+ return & CanceledError {details : d }
184+ }
177185 }
178- return & CanceledError {details : data }
186+ return & CanceledError {details : ErrorDetailsValues ( details ) }
179187}
180188
181189// NewContinueAsNewError creates ContinueAsNewError instance
@@ -192,14 +200,14 @@ func NewCanceledError(details ...interface{}) *CanceledError {
192200//
193201func NewContinueAsNewError (ctx Context , wfn interface {}, args ... interface {}) * ContinueAsNewError {
194202 // Validate type and its arguments.
195- workflowType , input , err := getValidatedWorkflowFunction (wfn , args )
196- if err != nil {
197- panic (err )
198- }
199203 options := getWorkflowEnvOptions (ctx )
200204 if options == nil {
201205 panic ("context is missing required options for continue as new" )
202206 }
207+ workflowType , input , err := getValidatedWorkflowFunction (wfn , args , options .dataConverter )
208+ if err != nil {
209+ panic (err )
210+ }
203211 if options .taskListName == nil || * options .taskListName == "" {
204212 panic ("invalid task list provided" )
205213 }
@@ -230,11 +238,14 @@ func (e *CustomError) Reason() string {
230238
231239// HasDetails return if this error has strong typed detail data.
232240func (e * CustomError ) HasDetails () bool {
233- return e .details .HasValues ()
241+ return e .details != nil && e . details .HasValues ()
234242}
235243
236244// Details extracts strong typed detail data of this custom error. If there is no details, it will return ErrNoData.
237245func (e * CustomError ) Details (d ... interface {}) error {
246+ if ! e .HasDetails () {
247+ return ErrNoData
248+ }
238249 return e .details .Get (d ... )
239250}
240251
@@ -255,11 +266,14 @@ func (e *TimeoutError) TimeoutType() shared.TimeoutType {
255266
256267// HasDetails return if this error has strong typed detail data.
257268func (e * TimeoutError ) HasDetails () bool {
258- return e .details .HasValues ()
269+ return e .details != nil && e . details .HasValues ()
259270}
260271
261272// Details extracts strong typed detail data of this error. If there is no details, it will return ErrNoData.
262273func (e * TimeoutError ) Details (d ... interface {}) error {
274+ if ! e .HasDetails () {
275+ return ErrNoData
276+ }
263277 return e .details .Get (d ... )
264278}
265279
@@ -270,11 +284,14 @@ func (e *CanceledError) Error() string {
270284
271285// HasDetails return if this error has strong typed detail data.
272286func (e * CanceledError ) HasDetails () bool {
273- return e .details .HasValues ()
287+ return e .details != nil && e . details .HasValues ()
274288}
275289
276290// Details extracts strong typed detail data of this error.
277291func (e * CanceledError ) Details (d ... interface {}) error {
292+ if ! e .HasDetails () {
293+ return ErrNoData
294+ }
278295 return e .details .Get (d ... )
279296}
280297
0 commit comments