github.com/operandinc/gqlgen@v0.16.1/docs/content/reference/errors.md (about)

     1  ---
     2  linkTitle: Handling Errors
     3  title: Sending custom error data in the graphql response
     4  description: Customising graphql error types to send custom error data back to the client using gqlgen.
     5  menu: { main: { parent: "reference", weight: 10 } }
     6  ---
     7  
     8  ## Returning errors
     9  
    10  All resolvers simply return an error to be sent to the user. The assumption is that any error message returned
    11  here is appropriate for end users. If certain messages aren't safe, customise the error presenter.
    12  
    13  ### Multiple errors
    14  
    15  To return multiple errors you can call the `graphql.Error` functions like so:
    16  
    17  ```go
    18  package foo
    19  
    20  import (
    21  	"context"
    22  
    23  	"github.com/vektah/gqlparser/v2/gqlerror"
    24  	"github.com/operandinc/gqlgen/graphql"
    25  )
    26  
    27  func (r Query) DoThings(ctx context.Context) (bool, error) {
    28  	// Print a formatted string
    29  	graphql.AddErrorf(ctx, "Error %d", 1)
    30  
    31  	// Pass an existing error out
    32  	graphql.AddError(ctx, gqlerror.Errorf("zzzzzt"))
    33  
    34  	// Or fully customize the error
    35  	graphql.AddError(ctx, &gqlerror.Error{
    36  		Path:       graphql.GetPath(ctx),
    37  		Message:    "A descriptive error message",
    38  		Extensions: map[string]interface{}{
    39  			"code": "10-4",
    40  		},
    41  	})
    42  
    43  	// And you can still return an error if you need
    44  	return false, gqlerror.Errorf("BOOM! Headshot")
    45  }
    46  ```
    47  
    48  They will be returned in the same order in the response, eg:
    49  
    50  ```json
    51  {
    52  	"data": {
    53  		"todo": null
    54  	},
    55  	"errors": [
    56  		{ "message": "Error 1", "path": ["todo"] },
    57  		{ "message": "zzzzzt", "path": ["todo"] },
    58  		{
    59  			"message": "A descriptive error message",
    60  			"path": ["todo"],
    61  			"extensions": { "code": "10-4" }
    62  		},
    63  		{ "message": "BOOM! Headshot", "path": ["todo"] }
    64  	]
    65  }
    66  ```
    67  
    68  ## Hooks
    69  
    70  ### The error presenter
    71  
    72  All `errors` returned by resolvers, or from validation, pass through a hook before being displayed to the user.
    73  This hook gives you the ability to customise errors however makes sense in your app.
    74  
    75  The default error presenter will capture the resolver path and use the Error() message in the response.
    76  
    77  You change this when creating the server:
    78  
    79  ```go
    80  package bar
    81  
    82  import (
    83  	"context"
    84  	"errors"
    85  
    86  	"github.com/vektah/gqlparser/v2/gqlerror"
    87  	"github.com/operandinc/gqlgen/graphql"
    88  	"github.com/operandinc/gqlgen/graphql/handler"
    89  )
    90  
    91  func main() {
    92  	server := handler.NewDefaultServer(MakeExecutableSchema(resolvers))
    93  	server.SetErrorPresenter(func(ctx context.Context, e error) *gqlerror.Error {
    94  		err := graphql.DefaultErrorPresenter(ctx, e)
    95  
    96  		var myErr *MyError
    97  		if errors.As(e, &myErr) {
    98  			err.Message = "Eeek!"
    99  		}
   100  
   101  		return err
   102  	})
   103  }
   104  
   105  ```
   106  
   107  This function will be called with the same resolver context that generated it, so you can extract the
   108  current resolver path and whatever other state you might want to notify the client about.
   109  
   110  ### The panic handler
   111  
   112  There is also a panic handler, called whenever a panic happens to gracefully return a message to the user before
   113  stopping parsing. This is a good spot to notify your bug tracker and send a custom message to the user. Any errors
   114  returned from here will also go through the error presenter.
   115  
   116  You change this when creating the server:
   117  
   118  ```go
   119  server := handler.NewDefaultServer(MakeExecutableSchema(resolvers)
   120  server.SetRecoverFunc(func(ctx context.Context, err interface{}) error {
   121      // notify bug tracker...
   122  
   123  		return gqlerror.Errorf("Internal server error!")
   124  })
   125  ```