Skip to content

question/bug: Is there a way to use custom errors for Goa's internal errors? #3717

@gabyx

Description

@gabyx

The example here shows how to return a custom error: https://github.com/goadesign/examples/blob/master/error/calc.go#L26
This is good but if one wants to customize the error type for a whole service, Goa still uses its own underlying ErrorResult type
which can not be customized at the moment or am I missing something?

Also the client uses ClientError: from goa/v3/http/client.go:

and a decode function in the client/encode_decode.go is generated like the blow extract
and any server error due to request decoding (ErrorResult) (e.g. missing field)
gets mapped into the default: case which returns a gohttp.ErrInvalidResponse. Is this correct?
We defined the errors cm#bad-request and cm#invalid-contract etc.

*Encode/Decode in Client:

func DecodeCreateContractResponse(decoder func(*http.Response) goahttp.Decoder, restoreBody bool) func(*http.Response) (any, error) {
	return func(resp *http.Response) (any, error) {
		// redacted .........
		switch resp.StatusCode {
		case http.StatusOK:
			// redacted ...
		case http.StatusBadRequest:
			en := resp.Header.Get("goa-error")
			switch en {
			case "cm#bad-request":
				var (
					body CreateContractCmBadRequestResponseBody
					err  error
				)
				err = decoder(resp).Decode(&body)
				if err != nil {
					return nil, goahttp.ErrDecodingError("cm", "createContract", err)
				}
				err = ValidateCreateContractCmBadRequestResponseBody(&body)
				if err != nil {
					return nil, goahttp.ErrValidationError("cm", "createContract", err)
				}
				return nil, NewCreateContractCmBadRequest(&body)
			case "cm#contract-invalid":
				var (
					body CreateContractCmContractInvalidResponseBody
					err  error
				)
				err = decoder(resp).Decode(&body)
				if err != nil {
					return nil, goahttp.ErrDecodingError("cm", "createContract", err)
				}
				err = ValidateCreateContractCmContractInvalidResponseBody(&body)
				if err != nil {
					return nil, goahttp.ErrValidationError("cm", "createContract", err)
				}
				return nil, NewCreateContractCmContractInvalid(&body)
			default:
				body, _ := io.ReadAll(resp.Body)
				return nil, goahttp.ErrInvalidResponse("cm", "createContract", resp.StatusCode, string(body))
			}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions