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

The service startup error could not be printed correctly #3101

Closed
cayller opened this issue Nov 28, 2023 · 2 comments
Closed

The service startup error could not be printed correctly #3101

cayller opened this issue Nov 28, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@cayller
Copy link

cayller commented Nov 28, 2023

What happened:

using register a custom server and using registrar, when custom server return a error, terminal can not print correct error description

What you expected to happen:

printing the correct error
image
but actually printing ctx canceled,because custom server return a error
image

How to reproduce it (as minimally and precisely as possible):

image
image
corresponding source code
image

Anything else we need to know?:

Environment:

  • Kratos version (use kratos -v):2.7.1
  • Go version (use go version):1.21
  • OS (e.g: cat /etc/os-release):
  • Others:
@cayller cayller added the bug Something isn't working label Nov 28, 2023
Copy link

dosubot bot commented Nov 28, 2023

🤖

Hello @cayller! I'm Dosu, a friendly bot here to assist you with your Kratos-related queries and concerns while we wait for a human maintainer. I'm here to help you solve bugs, answer questions, and guide you on becoming a contributor. Feel free to share more about your issue and I'll do my best to assist you!

The issue you're experiencing seems to be related to the default error decoder in Kratos. The DefaultErrorDecoder function is responsible for decoding HTTP errors. If the HTTP status code is between 200 and 299, it returns nil, indicating no error. However, for other status codes, it attempts to read the response body and unmarshal it into an errors.Error type. If this process fails, it returns a new error with the status code and an unknown reason.

The problem arises when the context is canceled. In such cases, the HTTP client's Do method returns an error, which is then passed to the DefaultErrorDecoder. However, since the context is canceled, the response is nil, and the decoder cannot read the body or unmarshal it into an errors.Error type. As a result, it returns a new error with the status code and an unknown reason, which is why you're seeing "ctx canceled" instead of the actual error description.

To resolve this issue, you can create a custom error decoder that handles context cancellation errors separately. Here's an example:

func CustomErrorDecoder(_ context.Context, res *http.Response) error {
    if res.StatusCode >= 200 && res.StatusCode <= 299 {
        return nil
    }
    if res == nil {
        return errors.New("Context was canceled")
    }
    defer res.Body.Close()
    data, err := io.ReadAll(res.Body)
    if err == nil {
        e := new(errors.Error)
        if err = CodecForResponse(res).Unmarshal(data, e); err == nil {
            e.Code = int32(res.StatusCode)
            return e
        }
    }
    return errors.Newf(res.StatusCode, errors.UnknownReason, "").WithCause(err)
}

Then, when creating your client, use the WithErrorDecoder option to use your custom error decoder:

client, err := NewClient(ctx, WithErrorDecoder(CustomErrorDecoder))

This way, when the context is canceled, your custom error decoder will return a more descriptive error message. You can find more information about this in the transport/http/client.go file in the Kratos repository.

Sources

@shenqidebaozi
Copy link
Sponsor Member

#3146

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants