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

Check errors #431

Merged
merged 17 commits into from
Dec 13, 2016
Merged

Check errors #431

merged 17 commits into from
Dec 13, 2016

Conversation

mcardosos
Copy link
Contributor

Fixes issue 428
Please take a look @vishrutshah @jhendrixMSFT

@@ -58,7 +58,9 @@ func AddAzureDockerVMExtensionConfiguration(role *vm.Role, dockerPort int, versi
return fmt.Errorf(errParamNotSpecified, "role")
}

ConfigureWithExternalPort(role, "docker", dockerPort, dockerPort, vm.InputEndpointProtocolTCP)
if err := ConfigureWithExternalPort(role, "docker", dockerPort, dockerPort, vm.InputEndpointProtocolTCP); err != nil {
panic(err)
Copy link
Member

Choose a reason for hiding this comment

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

Why not return err here like the other branches in this function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ohh, true that. Will change :D

return checkRespCode(resp.statusCode, []int{http.StatusCreated})
}

// CreateContainerIfNotExists creates a blob container if it does not exist. Returns
// true if container is newly created or false if container already exists.
func (b BlobStorageClient) CreateContainerIfNotExists(name string, access ContainerAccessType) (bool, error) {
func (b BlobStorageClient) CreateContainerIfNotExists(name string, access ContainerAccessType) (notExists bool, err error) {
Copy link
Member

Choose a reason for hiding this comment

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

Why was the bool return valued named? I don't see the name referenced in the method body. I see this same pattern in other methods too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I named the bool because if I name the error, all returning stuff should be named.
The error is named so errors from defer can be returned and checked.

Copy link
Member

Choose a reason for hiding this comment

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

I see, makes sense.

defer resp.body.Close()
defer func() {
err = resp.body.Close()
}()
if resp.statusCode == http.StatusCreated || resp.statusCode == http.StatusConflict {
return resp.statusCode == http.StatusCreated, nil
}
Copy link
Member

Choose a reason for hiding this comment

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

The function after this one, createContainer, needs to have the same fix applied.

Copy link
Member

Choose a reason for hiding this comment

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

OK after re-reading the implementation I don't think it does.

@jhendrixMSFT
Copy link
Member

Changes look good.

@jhendrixMSFT jhendrixMSFT mentioned this pull request Nov 1, 2016
@@ -31,3 +32,10 @@ script:
- go vet ./management/...
- test -z "$(golint ./Gododir/... | tee /dev/stderr)"
- go vet ./Gododir/...
- errcheck -ignoretests ./arm/...
Copy link
Contributor

Choose a reason for hiding this comment

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

can be shortened: set -e; for v in ./arm... ./datalake-store/... ./Gododir/...; do errcheck -ignoretests "$v"; done

func getResponseBody(response *http.Response) ([]byte, error) {
defer response.Body.Close()
func getResponseBody(response *http.Response) (out []byte, err error) {
defer func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not super ok with this one 1) response.Body can be nil 2) returning Close() error is a behavior change. also why do you add named returns?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm returning named results so the errors inside the defer function can actually be returned.
Question, will Close() return an error on an empty / nil response.Body? I that is the case then I agree it is not as useful to return an error from close, because ReadAll would just return an empty []byte.
Will fix

Copy link
Contributor

Choose a reason for hiding this comment

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

Question, will Close() return an error on an empty / nil response.Body?

it will panic with nil dereference error.

@@ -31,3 +32,6 @@ script:
- go vet ./management/...
- test -z "$(golint ./Gododir/... | tee /dev/stderr)"
- go vet ./Gododir/...
- test -z "$(set -e; for v in ./arm... ./datalake-store/... ./Gododir/...; do (errcheck -ignoretests "$v" | grep -v 'resp.body.Close()' | tee /dev/stderr); done)""
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. if you will have test -z, set -e is not necessary.

  2. instead of this grep hack, perhaps you can do:

defer func(){
     _ = resp.Body.Close()
}()
  1. can you please check all callers of getRequestBody() make sure that error from the request is nil and then go on reading the body? (if error from http.Do/Get/... is non-nil, then resp.Body will be nil, causing the panic in defer resp.Body.Close()

  2. You have grep -v 'resp.body.Close()' but I think body should be Body?

@mcardosos
Copy link
Contributor Author

Travis is passing. How does this look @ahmetalpbalkan ?

@@ -30,3 +31,6 @@ script:
- go vet ./management/...
- test -z "$(golint ./Gododir/... | tee /dev/stderr)"
- go vet ./Gododir/...
- set -e; for v in ./arm/... ./datalake-store/... ./Gododir/... ./management/... ./storage/...; do errcheck -ignoretests "$v"; done
Copy link
Contributor

Choose a reason for hiding this comment

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

are you sure errcheck returns with non-zero exitcode when it finds issues? if so you may still need the test -z.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Travis fails with errcheck, take a look at this build. And from errcheck documentation.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's fair. I think I tried integrating errcheck long time ago manually and it just came with tons of changes which were not necessary (see my other comment). I just started to recall that...

@@ -439,7 +439,9 @@ func (b BlobStorageClient) ListContainers(params ListContainersParameters) (Cont
if err != nil {
return out, err
}
defer resp.body.Close()
defer func() {
Copy link
Contributor

Choose a reason for hiding this comment

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

@mcardosos I strongly suggest turning off errcheck for this package. It makes the code really ugly with this change. It's idiomatic go to call defer resp.body.Close() and discard the output implicitly.

I am sorry that I did not see this coming. I thought you were just going to change 1-2 places in management package. But this results in quite ugly code for this package.

We must use static analysis tools like this occasionally to catch bugs but for cases like these, they are deliberate decisions and we should not be using hacks like this all over the place to suppress the static analysis tool. I think errcheck is a bit extreme. Perhaps just run errcheck | grep -v Close or something again. :(

h := hmac.New(sha256.New, c.accountKey)
h.Write([]byte(message))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
if _, err := h.Write([]byte(message)); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

Kinda mixed feelings about changing this. the hmac.inner == sha256 type's Write() will never return an error as everything is in-memory. 😕

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah this change causes many changes in the upstream callers whereas the error can be just discarded. wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

errcheck doesn't like it. In the other hand, gas doesn't really care. Looking at all this again, I actually think gas is more reasonable. I think it would be better if instead of gas -skip=*/arm/*/models.go -skip=*/management/examples/*.go -skip=*vendor* -skip=*/Gododir/* ./..., I rewrote that line so for all this skipped files I just exclude whatever rule they break. For example, I'm skipping all the models.go files because they "break" rule G101.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

And we can then get rid of errcheck :D

@@ -319,7 +319,7 @@ func (c QueueServiceClient) DeleteMessage(queue, messageID, popReceipt string) e
if err != nil {
return err
}
defer resp.body.Close()
deferresp.body.Close()
Copy link
Contributor

Choose a reason for hiding this comment

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

error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Clumsy me

h := hmac.New(sha256.New, c.accountKey)
h.Write([]byte(message))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
if _, err := h.Write([]byte(message)); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

yeah this change causes many changes in the upstream callers whereas the error can be just discarded. wdyt?

@mcardosos mcardosos force-pushed the check-err branch 3 times, most recently from 50791d3 to 9a1b963 Compare December 12, 2016 23:35
@marstr marstr merged commit 2fb0ef4 into Azure:master Dec 13, 2016
@mcardosos mcardosos deleted the check-err branch January 12, 2017 21:09
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.

5 participants