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

Remove usage of log.Fatal from httpclient.go; return an error object instead (FF-1934) #36

Merged
merged 2 commits into from
Apr 16, 2024

Conversation

leoromanovsky
Copy link
Member

@leoromanovsky leoromanovsky commented Apr 15, 2024

observation

When the Eppo API returns an HTTP >= 500, the SDK emits a log.Fatal. I believe this was added without fully realizing its side-effect behavior of immediately exiting the program with status 1.

In effect our http_client.go library is deciding for the rest of the SDK what behavior an HTTP 500 response should have. It is best to simply return this information upstream and let the relevant calling code make that determination, otherwise our server SDK customers will have regular process restarts.

changes

  • remove all usages of log.Fatal
  • add an error object response to get method of http_client.go
  • adds unit tests for http_client.go

The changes in SDK behavior are that the program will no longer exit on http 500; this case will simply log.

if err != nil {
log.Fatal(err)
return "", err // Return an empty string and the error
Copy link
Member Author

Choose a reason for hiding this comment

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

According to the docs:

// An error is returned if caused by client policy (such as
// CheckRedirect), or failure to speak HTTP (such as a network
// connectivity problem). A non-2xx status code doesn't cause an
// error.

We should almost never expect to see this condition be executed.

Comment on lines 57 to +63
if resp.StatusCode == 401 {
hc.isUnauthorized = true
return "", fmt.Errorf("unauthorized access") // Return an error indicating unauthorized access
}

if resp.StatusCode >= 500 {
return "", fmt.Errorf("server error: %d", resp.StatusCode) // Handle server errors (status code > 500)
Copy link
Member Author

Choose a reason for hiding this comment

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

Another approach we can take here is to return "positive" when http is 2xx and have a generic error message otherwise.

@leoromanovsky leoromanovsky marked this pull request as ready for review April 15, 2024 22:01
Comment on lines +43 to +47
result, err := ecr.httpClient.get(RAC_ENDPOINT)
if err != nil {
fmt.Println("Failed to fetch RAC response", err)
return
}
Copy link
Member Author

Choose a reason for hiding this comment

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

I need to review canonical logging practice in go - I believe it would be better here to just log at the debug level.

Copy link
Contributor

Choose a reason for hiding this comment

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

or perhaps warn level since its unexpected/unintended, but handled

Copy link
Member Author

Choose a reason for hiding this comment

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

standard log package in Go does not directly support different logging levels like Warning. You would typically use log.Println or log.Printf for logging purposes and include a warning message manually. To accomplish this we will be using a third-party logging library that supports log levels, such as logrus, zap, or others.

I believe this is something we should move to (see comment from lucas below) to give our customers customization to use their own logger and I've added it to the scope of our upcoming debugging project.

Copy link
Contributor

@aarsilv aarsilv left a comment

Choose a reason for hiding this comment

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

Looks good to me!

Comment on lines +43 to +47
result, err := ecr.httpClient.get(RAC_ENDPOINT)
if err != nil {
fmt.Println("Failed to fetch RAC response", err)
return
}
Copy link
Contributor

Choose a reason for hiding this comment

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

or perhaps warn level since its unexpected/unintended, but handled

"testing"
)

func TestHttpClientGet(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

🙌

result := ecr.httpClient.get(RAC_ENDPOINT)
result, err := ecr.httpClient.get(RAC_ENDPOINT)
if err != nil {
fmt.Println("Failed to fetch RAC response", err)

Choose a reason for hiding this comment

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

have you consider exposing a log in your sdk like this https://github.com/hyperjumptech/grule-rule-engine/blob/e4e90fe744ffffc1010edb7d12c5693a0b9ce477/logger/Logger.go#L79

like that you also extend the SDK for your clients to have their own log passed to your sdk and we can have better visibility.

Copy link
Member Author

Choose a reason for hiding this comment

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

@lucasflink thank you for the suggestion and attached link - yes this is a great idea. we have an upcoming project starting imminently to improve the debug-ability of our SDKs and service for customers and I've included this in-scope.

I'm familiar with zap from working at Uber do you view as preferred? I will investigate whether a common interface (https://github.com/go-logr/logr) is possible.

Choose a reason for hiding this comment

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

yes, most of the projects I worked with use the zap from Uber and I would also vow to use it. But maybe also consider creating your own interface with the common methods used for logging and like that any lib can be used and we would not be tight to only zap.

@leoromanovsky leoromanovsky merged commit 66c5367 into main Apr 16, 2024
3 checks passed
@leoromanovsky leoromanovsky deleted the lr/ff-1934/golang-log-fatal branch April 16, 2024 17:21
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.

None yet

3 participants