Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update docs for Twirp Errors - edits #369

Merged
merged 3 commits into from
Sep 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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=<your-github-username> CURRENT_BRANCH=gh-pages USE_SSH=true npm run publish-gh-pages
```

## Making a New Release

Expand Down
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
48 changes: 25 additions & 23 deletions docs/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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"
Expand All @@ -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).

Expand Down Expand Up @@ -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).

Expand Down