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

Enh/improve error handling #9

Merged
merged 9 commits into from
Oct 13, 2019
Merged

Enh/improve error handling #9

merged 9 commits into from
Oct 13, 2019

Conversation

leiter-jakab
Copy link

@leiter-jakab leiter-jakab commented Oct 9, 2019

Hi IPFS Team, great project. Hoping to help with this change. Not sure if this is the correct solution, but I would love to hear your feedback.

Regards,
Gergo

As described in #6434, I moved error handing to the Lock function.
I changed go.mod by accident. Removing the change with this commit.
Copy link
Member

@Stebalien Stebalien left a comment

Choose a reason for hiding this comment

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

Thanks!

fslock.go Outdated
if err != nil {
// EAGAIN == someone else has the lock
if err == syscall.EAGAIN {
return lk, errors.New(fmt.Sprintf("Someone else has the lock: %s", filepath.Join(confdir, lockFile)))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return lk, errors.New(fmt.Sprintf("Someone else has the lock: %s", filepath.Join(confdir, lockFile)))
return lk, fmt.Errorf("Someone else has the lock: %s", filepath.Join(confdir, lockFile))

fslock.go Outdated
@@ -35,30 +59,20 @@ func Locked(confdir, lockFile string) (bool, error) {

lk, err := Lock(confdir, lockFile)
if err != nil {
Copy link
Member

Choose a reason for hiding this comment

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

Given that we're now parsing the error in Lock, what if we just had Lock return a custom error type on failure? We could return an error implementing:

type myerror interface {
  Permission() bool // returns true if this is a permission error.
  Locked() bool // returns true if this error means that the lock has already been taken.
}

Then we can provide two functions to determine why taking the lock failed:

func IsLocked(err) bool { ... }
func IsPermission(err) bool { ... }

This function would be reduced to an IsLocked(err) call (and a debug statement).

Copy link
Author

@leiter-jakab leiter-jakab Oct 10, 2019

Choose a reason for hiding this comment

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

Sounds good to me. It felt very convoluted and weird that Lock is producing those specific errors and Locked is checking strings to do a very similar error categorization.

Copy link
Author

Choose a reason for hiding this comment

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

@Stebalien I have been thinking about this and I have to learn more about idiomatic error handling in Go before I make any changes.

On the other hand, I'm not sure that the original issue has been solved by my changes.

What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

The original issue has been solved, I'm just trying to avoid parsing errors in two places.

Use fmt.Errorf to create error messages in a clear, idiomatic way.
I did not remove the errors package after changing error formatting. Fixing it with this commit.
fslock.go Outdated
@@ -35,30 +59,20 @@ func Locked(confdir, lockFile string) (bool, error) {

lk, err := Lock(confdir, lockFile)
if err != 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 original issue has been solved, I'm just trying to avoid parsing errors in two places.

fslock.go Outdated
if strings.Contains(err.Error(), "already locked") {
log.Debugf("Lock is already held by us: %s", filepath.Join(confdir, lockFile))
if strings.Contains(errCase, "Someone else has the lock:") {
log.Debugf(errCase)
Copy link
Member

Choose a reason for hiding this comment

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

This should be log.Debug(errCase) (otherwise, we'll parse errCase for string format specifiers).

fslock.go Outdated
log.Debugf("Lock fails on permissions error")
return false, errPerm(confdir)
if strings.Contains(errCase, "permissions denied") {
log.Debugf(errCase)
Copy link
Member

Choose a reason for hiding this comment

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

ditto.

fslock.go Outdated
log.Debugf("Can't lock file: %s.\n reason: %s", filepath.Join(confdir, lockFile), err.Error())
errCase := err.Error()
if strings.Contains(errCase, "Lock is already held by us:") {
log.Debugf(errCase)
Copy link
Member

Choose a reason for hiding this comment

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

ditto

Introduced custom errors:
* LockError
* PermError
They implement the error interface.
IsLocked function now checks error type insead of content of the error message.
* Use PathError to:
  * Keep `os.IsPermission` working.
  * Help with tooling that looks for path errors.
* Tell users to use `errors.As` to determine if an error is a "locked" error.
@Stebalien
Copy link
Member

I went digging through some go error documentation and realized we could use the built-in error types. I took the liberty of making those changes rather than try to change direction on you again.

@Stebalien Stebalien merged commit 5eb2643 into ipfs:master Oct 13, 2019
@leiter-jakab
Copy link
Author

I went digging through some go error documentation and realized we could use the built-in error types. I took the liberty of making those changes rather than try to change direction on you again.

Very nice, I learned quite a bit. Could you please point me to the documentation where you found the relevant info? Thanks.

@leiter-jakab leiter-jakab deleted the enh/improve-error-handling branch October 14, 2019 10:27
@Stebalien
Copy link
Member

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