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

rule.unhandled-error does not work for nested methods #350

Open
jBugman opened this issue Feb 21, 2020 · 5 comments
Open

rule.unhandled-error does not work for nested methods #350

jBugman opened this issue Feb 21, 2020 · 5 comments
Assignees
Labels

Comments

@jBugman
Copy link

jBugman commented Feb 21, 2020

Describe the bug
Consider some abstract function/method ReturnsError() error
There are three general cases how it could be called

  1. ReturnsError() — catches ok
  2. struct.ReturnsError() — catches ok
  3. struct.field.ReturnsError() — ignored by revive

To Reproduce
This is with revive v1.0.1

[rule.unhandled-error]
  arguments = ["fmt.Printf"]
  severity = "error"

Expected behavior
Rule should work for all described cases.

@chavacava chavacava self-assigned this Feb 24, 2020
@chavacava
Copy link
Collaborator

Hi @jBugman, thanks for reporting this issue. I will work on it this week.

@chavacava
Copy link
Collaborator

Hi @jBugman, I've tryed to reproduce the bug with

import (
	"fmt"
)

type r struct {
	s s
}

type s struct{}

func (s *s) returnsError() error {
	return fmt.Errorf("handle it!")
}

func unhandledError3() {
	myS := &s{}
	myS.returnsError()
	myR := &r{myS}
	myR.s.returnsError()
}

But revive correctly catches the last case

fixtures/unhandled-error.go:19:2: Unhandled error in call to function myS.returnsError
fixtures/unhandled-error.go:21:2: Unhandled error in call to function myR.s.returnsError

@jBugman
Copy link
Author

jBugman commented Feb 24, 2020

Hi, @chavacava as it turns out that example works for me also. But I modified it to something more realistic and it doesn't anymore. Looks like imported structures break something.

main.go

package main

import (
	"./pkg"
)

type r struct {
	s pkg.S
}

func main() {
	myS := &pkg.S{}
	myS.ReturnsError()
	myR := &r{*myS}
	myR.s.ReturnsError()
}

pkg/pkg.go

package pkg

import "fmt"

type S struct{}

func (s *S) ReturnsError() error {
	return fmt.Errorf("handle it!")
}
✘ 2 problems (1 error, 1 warning)

Errors:
  1  unused-receiver  

Warnings:
  1  error-strings  

@chavacava
Copy link
Collaborator

It seems that the problem is not related to imported structures, revive behaves as expected for the following code:

import (
	"net/http"
)

func foo() {
	(&http.Request{}).MultipartForm.RemoveAll()
}

@mgechev mgechev added the bug label Mar 3, 2020
@chavacava
Copy link
Collaborator

The rule needs type information to identify functions returning values of type error, that is why at the beginning of the rule execution over a file, it performs type-checking on the package.
Paradoxically, we do not check for potential errors from the call to file.pkg.TypeCheck() therefore the rule will apply without type information thus no failures are detected on those functions for which no type information is available.
I've tested aborting execution if type-checking fails but type checking fails if there are imports to packages others than those of the standard library.
For example, when linting

package main

import (
	"gopkg.in/src-d/go-git.v4"
)

func main() {
	r := &git.Remote{}
	r.Push(nil)
}

I get the following error when type-checking:

main.go:4:2: could not import gopkg.in/src-d/go-git.v4 (can't find import: gopkg.in/src-d/go-git.v4)

Even if the code successfully compiles with go build

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

No branches or pull requests

3 participants