diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e5ff23f2..e80854bc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -49,19 +49,20 @@ dependencies we know about, build the core, and run tests. A few notes: ## Contributing Documentation -Twirp's docs are generated with [Docusaurus](https://docusaurus.io/). You can -safely edit anything inside the [docs](./docs) directory, adding new pages or -editing them. You can edit the sidebar by editing -[website/sidebars.json](./website/sidebars.json). +Twirp's docs are generated with [Docusaurus](https://docusaurus.io/). You can safely edit anything inside the [docs](./docs) directory, adding new pages or editing them. You can edit the sidebar by editing [website/sidebars.json](./website/sidebars.json). -Then, to render your changes, run docusaurus's local server. See [Install docusaurus on your machine](https://docusaurus.io/docs/en/installation.html). +To render and review your changes, run docusaurus's local server. See [Install docusaurus on your machine](https://docusaurus.io/docs/en/installation.html). -1. `cd website` -2. `npm install` -3. `npm start` -4. Navigate to http://localhost:3000/twirp. +1. `cd website` +2. `npm install` +3. `npm start` +4. Navigate to http://localhost:3000/twirp to see how it looks. -Follow [this guide](https://docusaurus.io/docs/en/tutorial-publish-site) to publish changes to the `gh-pages` branch. +Publish the new docs on the `gh-pages` branch. See [this guide](https://docusaurus.io/docs/en/tutorial-publish-site) for details. + +``` +GIT_USER= CURRENT_BRANCH=gh-pages USE_SSH=true npm run publish-gh-pages +``` ## Making a New Release diff --git a/README.md b/README.md index dbb8e3c4..94009953 100644 --- a/README.md +++ b/README.md @@ -15,14 +15,13 @@ extremely-well-tested-and-high-performance `net/http` Server. It can run on HTTP Along the way, you get autogenerated clients and a simple, smart framework for passing error messages. Nice! -For more on the motivation behind Twirp (and a comparison to REST APIs and gRPC), the -[announcement blog post](https://blog.twitch.tv/en/2018/01/16/twirp-a-sweet-new-rpc-framework-for-go-5f2febbf35f/) -is a good read. +Read more about the motivation behind on the [announcement blog post](https://blog.twitch.tv/en/2018/01/16/twirp-a-sweet-new-rpc-framework-for-go-5f2febbf35f/). ### Documentation * [Getting Started](https://twitchtv.github.io/twirp/docs/intro.html) * [Usage Example](https://twitchtv.github.io/twirp/docs/example.html) + * [Errors](https://twitchtv.github.io/twirp/docs/errors.html) * More: https://twitchtv.github.io/twirp/ ### Implementations in other languages diff --git a/docs/errors.md b/docs/errors.md index 61402bc2..9c7cffbe 100644 --- a/docs/errors.md +++ b/docs/errors.md @@ -4,9 +4,29 @@ title: "Errors" sidebar_label: "Errors" --- +A Twirp error has: + + * **code**: identifies the type of error. + * **msg**: free-form message with detailed information about the error. It is meant for humans, to assist with debugging. Programs should not try to parse the error message. + * **meta**: (optional) key-value pairs with arbitrary string metadata. + +## Error Codes + +Valid Twirp error codes (HTTP status): + + * `internal` (500) + * `not_found` (404) + * `invalid_argument` (400) + * `unauthenticated` (401) + * `permission_denied` (403) + * `already_exists` (409) + * ... more on the [Errors Spec](spec_v7.md#error-codes) + +To map a [twirp.ErrorCode](https://pkg.go.dev/github.com/twitchtv/twirp#ErrorCode) into the equivalent HTTP status, use the helper [twirp.ServerHTTPStatusFromErrorCode](https://pkg.go.dev/github.com/twitchtv/twirp#ServerHTTPStatusFromErrorCode)). + ## Overview -Service endpoint returns a Twirp error: +A Twirp endpoint returns a [twirp.Error](https://pkg.go.dev/github.com/twitchtv/twirp#Error). For example, a "Permission ```go func (s *Server) Foo(ctx context.Context, req *pb.FooRequest) (*pb.FooResp, error) { @@ -17,7 +37,7 @@ func (s *Server) Foo(ctx context.Context, req *pb.FooRequest) (*pb.FooResp, erro Twirp serializes the response as a JSON with `code` and `msg` keys: ```json -// HTTP status code: 403 +// HTTP status: 403 { "code": "permission_denied", "msg": "this door is closed" @@ -28,33 +48,15 @@ The auto-generated client de-serializes and returns the same Twirp error: ```go resp, err := client.Foo(ctx, req) -if err != nil { - err.Error() //=> "twirp error permission_deined: this door is closed" - - twerr := err.(twirp.Error) +if twerr, ok := err.(twirp.Error); ok { twerr.Code() // => twirp.PermissionDenied twerr.Msg() //=> "this door is closed" } ``` -## Error Codes - -Valid Twirp Error Codes: - - * `internal` (500) - * `not_found` (404) - * `invalid_argument` (400) - * `unauthenticated` (401) - * `permission_denied` (403) - * `already_exists` (409) - * ... see all available codes on the [Errors Spec](spec_v7.md#error-codes). - -Twirp services map each error code to a equivalent HTTP status to make it easy to check for errors on middleware (See [twirp.ServerHTTPStatusFromErrorCode](https://pkg.go.dev/github.com/twitchtv/twirp#ServerHTTPStatusFromErrorCode)). - - ## Server Side: Returning Error Responses -A Twirp endpoint may return an error. If the error value implements the [twirp.Error](https://pkg.go.dev/github.com/twitchtv/twirp#Error) interface, it will be serialized and received by the client with the exact same `code`, `msg` and `meta` properties. +A Twirp endpoint may return an error. If the error value implements the interface, it will be serialized and received by the client with the exact same `code`, `msg` and `meta` properties. The `twirp` package provides error constructors for each code. For example, to build an internal error: `twirp.Internal.Error("oops")`. There is also a generic constructor [twirp.NewError](https://pkg.go.dev/github.com/twitchtv/twirp#NewError). Anything that implements the `twirp.Error` interface counts as a Twirp error. Check the [errors.go file for details](https://github.com/twitchtv/twirp/blob/main/errors.go). @@ -112,7 +114,7 @@ func (s *Server) FindUser(ctx context.Context, req *pb.FindUserRequest) (*pb.Fin } ``` -### Error responses from outside Twirp endpoints +#### Middleware, outside Twirp endpoints Twirp services can be [muxed with other HTTP services](mux.md). For consistent responses and error codes _outside_ Twirp servers, such as HTTP middleware, you can call [twirp.WriteError](https://pkg.go.dev/github.com/twitchtv/twirp#WriteError).