I want to create a placeholder in context
object to let the downstream code to fill the error
in context, so when program exiting I can capture the final error, but the following code doesn't work.
I am expecting to get the address of a variable which type is error
, like a C style pointer to a pointer, and fill the address with real error object later.
Can someone help me that why this doesn't work as expected?
func contextWithError_test() {
ctx := context.Background()
ctx = contextWithFinalError(ctx)
fillError(ctx)
finalError := FinalErrorFromContext(ctx)
if finalError != nil {
fmt.Println(*finalError)
}
}
func fillError(ctx1 context.Context) {
var err error = errors.New("something wrong")
finalError := FinalErrorFromContext(ctx1)
if finalError != nil {
finalError = &err
}
}
func contextWithFinalError(ctx context.Context) context.Context {
var finalError error
return context.WithValue(ctx, finalErrorKey, &finalError)
}
func FinalErrorFromContext(ctx context.Context) *error {
finalError, ok := ctx.Value(finalErrorKey).(*error)
if ok {
return finalError
}
return nil
}
PS I already find a way to achieve my goal, I need to declare a new type to wrap the error:
type ErrorWrapper struct {
finalError error
}
And embed the address of an ErrorWrapper
object in context
.
But does anyone know why the initial version doesn't work?
You do
finalError := FinalErrorFromContext(ctx1)
if finalError != nil {
finalError = &err
}
but probably mean
finalError := FinalErrorFromContext(ctx1)
if finalError != nil {
*finalError = err
}
You don't want to reassign finalError
, but the variable it is pointing to.