Skip to content

Commit

Permalink
Forward error types as their string representation (#131)
Browse files Browse the repository at this point in the history
By default go serializes `error` types as an empty struct `{}`, this
patch would adjust that so that errors are serialized as their string
representation by calling `Error()` on any non-nil types that implement
the error interface.

This should be an improvement over the current state as it now allows
identifying the cause of an error from the RPC client. An alternative
could be to serialize the error as a struct of `{"type": <>, "message":
<>}` using reflection to get the type name (and package path) of the
error though I'm not sure if it's necessary and I'd have to check how
easy that would be to get working.
  • Loading branch information
DerAndereAndi authored Nov 2, 2024
2 parents 7f7579a + 052c055 commit 73d0d7f
Showing 1 changed file with 20 additions and 2 deletions.
22 changes: 20 additions & 2 deletions examples/remote/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,23 @@ func isExportedOrBuiltinType(t reflect.Type) bool {
return token.IsExported(t.Name()) || t.PkgPath() == ""
}

// json.Marshall won't marshall error types, marshall as string
func errorAsJson(v reflect.Value) interface{} {
if v.IsNil() {
// passthrough nil as nil, otherwise nil.(error) will panic
return nil
} else {
return v.Interface().(error).Error()
}
}

func transformReturnValues(values []reflect.Value) []interface{} {
result := make([]interface{}, len(values))

for i, e := range values {
switch e.Type() {
valueType := e.Type()

switch valueType {
case reflect.TypeFor[spineapi.DeviceRemoteInterface]():
result[i] = e.Interface().(spineapi.DeviceRemoteInterface).Address()
case reflect.TypeFor[[]spineapi.DeviceRemoteInterface]():
Expand All @@ -51,12 +63,18 @@ func transformReturnValues(values []reflect.Value) []interface{} {
}
result[i] = transformedValues
default:
result[i] = e.Interface()
switch {
case valueType.Implements(reflect.TypeFor[error]()):
result[i] = errorAsJson(e)
default:
result[i] = e.Interface()
}
}
}

return result
}

func WriteKey(cert tls.Certificate, path string) error {
file, err := os.Create(path)
if err != nil {
Expand Down

0 comments on commit 73d0d7f

Please sign in to comment.