Changes:
- PR #323: Match service errors with
errors.As
instead of a type cast. Service implementations can now use their own error types if they implement thetwirp.Error
interface, but also if they wrap another Twirp error, or if theyimplement the methodAs(interface{}) bool
. See docs on Twirp Erros for more details. - PR #299: ServerOption
twirp.WithServerJSONCamelCaseNames(true)
configures JSON serialization to use the proto3 standard serialization method instead of the Twirp default to use the original proto names. When enabled, the JSON field names will belowerCamelCase
by default. If thejson_name
field option is used in the proto file, the specified value will be used as the key instead. - PR #318: Removed example Python client generator. This repo contains the Go implementation only now.
- PR #319 refactors ServerOptions and ClientOptions to allow new options in the future without forcing version updates.
- PR #321 and #313 improves and simplifies the CI build process, running clientcompat tests and removing faulty coverage checks.
- PR #312 sorts generated code imports so the generator always produces the same output.
Update instructions:
- Required Go version
1.13+
is needed for the errors package Is/As/Unwrap functions. - Runtime library is backwards compatible, can be safely updated to
v8.1.0
. - Generated clients are backwards compatible, but will require the importer to update their Twirp runtime library.
- The PR #323 introduces a potential breaking change for services. Read below for safe update instructions.
Previous Twirp services (v8.0.0
and older) check if returned errors are Twirp errors with a type-cast:
twerr, ok := err.(twirp.Error)
Newer Twirp services (v8.1.0
) will check if returned errors are Twirp errors by matching with errors.As
:
var twerr twirp.Error
ok := errors.As(err, &twerr)
Matching with errors.As
is similar to the type-cast, but it can also unwrap errors of the same type. Before you update to version v8.1.0
, please double check if any non-twirp errors returned by your service are not accidentally wrapping another Twirp error that should not be returned on the API. In particular, look for instances of fmt.Errorf("foo: %w", twerr)
, using %w
for wrapping other Twirp errors, for example:
// Calling another Twirp service from a Twirp method handler
resp, clientErr := anotherService.MyMethod(ctx, req)
if clientErr != nil {
// Wrapping another Twirp error will expose the inner error on v8.1.0
err := fmt.Errorf("otherService: %w", clientErr)
return nil, err
}
If you believe your service may be mistakenly wrapping other Twirp errors, you can explicitly wrap the error as an internal:
return nil, twirp.InternalErrorWith(err)
You could also use this error hook to identify possible discrepancies before updating to the new version. In the other hand, if your service was already using idiomatic Go errors, the new implementation will give you more power to your own Twirp error implementations.