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

Fix/4xx logs #1295

Closed
wants to merge 4 commits into from
Closed

Fix/4xx logs #1295

wants to merge 4 commits into from

Conversation

Umang01-hash
Copy link
Member

@Umang01-hash Umang01-hash commented Dec 11, 2024

Pull Request Template

Description:

Checklist:

  • I have formatted my code using goimport and golangci-lint.
  • All new code is covered by unit tests.
  • This PR does not decrease the overall code coverage.
  • I have reviewed the code comments and documentation for clarity.

Thank you for your contribution!

Comment on lines 162 to 176
func isHTTPError(err error) bool {
httpErrors := []error{
&gofrHTTP.ErrorEntityAlreadyExist{},
&gofrHTTP.ErrorEntityNotFound{},
&gofrHTTP.ErrorInvalidParam{},
&gofrHTTP.ErrorMissingParam{},
}
for _, knownErr := range httpErrors {
if errors.As(err, &knownErr) {
return true
}
}

return false
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have to do this, it means you could do better with the struct definition

Suggested change
func isHTTPError(err error) bool {
httpErrors := []error{
&gofrHTTP.ErrorEntityAlreadyExist{},
&gofrHTTP.ErrorEntityNotFound{},
&gofrHTTP.ErrorInvalidParam{},
&gofrHTTP.ErrorMissingParam{},
}
for _, knownErr := range httpErrors {
if errors.As(err, &knownErr) {
return true
}
}
return false
}
func isHTTPError(err error) bool {
return errors.Is(err, gofrHTTP.Error) {
}

Now let's move to gofr http package

Here is the current code for ErrorEntityNotFound

// ErrorEntityNotFound represents an error for when an entity is not found in the system.
type ErrorEntityNotFound struct {
        Name  string
        Value string
}

func (e ErrorEntityNotFound) Error() string {
        // For ex: "No entity found with id: 2"
        return fmt.Sprintf("No entity found with %s: %s", e.Name, e.Value)
}

func (ErrorEntityNotFound) StatusCode() int {
        return http.StatusNotFound
}

Let's define a error, then add a method to ErrorEntityNotFound

var ErrCommon = errors.New("HTTP error")

func (ErrorEntityNotFound) UnWrap() error {
        return ErrCommon
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You changed the implementation

Please consider what I suggested anyway

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can even define errCommon as unexported

And add this to http package

func IsHTTPError(err error) bool {
    return errors.Is(err, errCommon)
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ccoVeille the current code of the errors in Http package represents different structs for various scenarios like entity not found, entity already exist, missing param, invalid param etc.

Each of these structs are implementing a Error() string as well as StatusCode() int methods that help us to set the statuscode from framework if any of them has been used.

I don't think we can entirely change that.

But I would really like if you can review the new implementation for logError and tell how can we improve on it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ccoVeille we can't use errors.Is as it will match the exact value (then the populated fields in the error struct will be treated as different error)

So based on your comment can we do something like this:

import (
    "errors"
    gofrHTTP "path/to/gofrHTTP"
)

// Log the error (if any) with traceID and errorMessage.
func (h handler) logError(traceID string, err error) {
    if err != nil {
        errorLog := &ErrorLogEntry{TraceID: traceID, Error: err.Error()}

        if isKnownError(err) {
            h.container.Logger.Info(errorLog)
        } else {
            h.container.Logger.Error(errorLog)
        }
    }
}

func isKnownError(err error) bool {
    switch {
    case isEntityAlreadyExistError(err):
        return true
    case isEntityNotFoundError(err):
        return true
    case isInvalidParamError(err):
        return true
    case isMissingParamError(err):
        return true
    default:
        return false
    }
}

func isEntityAlreadyExistError(err error) bool {
    var target *gofrHTTP.ErrorEntityAlreadyExist
    return errors.As(err, &target)
}

func isEntityNotFoundError(err error) bool {
    var target *gofrHTTP.ErrorEntityNotFound
    return errors.As(err, &target)
}

func isInvalidParamError(err error) bool {
    var target *gofrHTTP.ErrorInvalidParam
    return errors.As(err, &target)
}

func isMissingParamError(err error) bool {
    var target *gofrHTTP.ErrorMissingParam
    return errors.As(err, &target)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree, mainly because that's the purpose of adding Unwrap

I could work on a better code, but I don't have time yet

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ccoVeille will wait for your suggestion on a better code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened #1298

@Umang01-hash
Copy link
Member Author

Closing this PR as the work of this PR has been addressed in PR #1298.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants