-
Notifications
You must be signed in to change notification settings - Fork 60
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
More robust error responses #24
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package vcs | ||
|
||
import "errors" | ||
|
||
// The vcs package provides ways to work with errors that hide the underlying | ||
// implementation details but make them accessible if needed. For basic errors | ||
// that do not have underlying implementation specific details or the underlying | ||
// details are likely not necessairy there are errors for comparison. | ||
// | ||
// For example: | ||
// | ||
// ci, err := repo.CommitInfo("123") | ||
// if err == vcs.ErrRevisionUnavailable { | ||
// // The commit id was not available in the VCS. | ||
// } | ||
// | ||
// There are other times where getting the details are more useful. For example, | ||
// if you're performing a repo.Get() and an error occurs. In general you'll want | ||
// to consistently know it failed. But, you may want to know the underlying | ||
// details (opt-in) to them. For those cases there is a different form of error | ||
// handling. | ||
// | ||
// For example: | ||
// | ||
// err := repo.Get() | ||
// if err != nil { | ||
// // A RemoteError was returned. This has access to the output of the | ||
// // vcs command, original error, and has a consistent cross vcs message. | ||
// } | ||
// | ||
// The errors returned here can be used in type switches to detect the underlying | ||
// error. For example: | ||
// | ||
// switch err.(type) { | ||
// case *vcs.RemoteError: | ||
// // This an error connecting to a remote system. | ||
// } | ||
// | ||
// For more information on using type switches to detect error types you can | ||
// read the Go wiki at https://github.com/golang/go/wiki/Errors | ||
|
||
var ( | ||
// ErrWrongVCS is returned when an action is tried on the wrong VCS. | ||
ErrWrongVCS = errors.New("Wrong VCS detected") | ||
|
||
// ErrCannotDetectVCS is returned when VCS cannot be detected from URI string. | ||
ErrCannotDetectVCS = errors.New("Cannot detect VCS") | ||
|
||
// ErrWrongRemote occurs when the passed in remote does not match the VCS | ||
// configured endpoint. | ||
ErrWrongRemote = errors.New("The Remote does not match the VCS endpoint") | ||
|
||
// ErrRevisionUnavailable happens when commit revision information is | ||
// unavailable. | ||
ErrRevisionUnavailable = errors.New("Revision unavailable") | ||
) | ||
|
||
// RemoteError is returned when an operation fails against a remote repo | ||
type RemoteError struct { | ||
vcsError | ||
} | ||
|
||
// NewRemoteError constructs a RemoteError | ||
func NewRemoteError(msg string, err error, out string) error { | ||
e := &RemoteError{} | ||
e.s = msg | ||
e.e = err | ||
e.o = out | ||
|
||
return e | ||
} | ||
|
||
// LocalError is returned when a local operation has an error | ||
type LocalError struct { | ||
vcsError | ||
} | ||
|
||
// NewLocalError constructs a LocalError | ||
func NewLocalError(msg string, err error, out string) error { | ||
e := &LocalError{} | ||
e.s = msg | ||
e.e = err | ||
e.o = out | ||
|
||
return e | ||
} | ||
|
||
type vcsError struct { | ||
s string | ||
e error // The original error | ||
o string // The output from executing the command | ||
} | ||
|
||
// Error implements the Error interface | ||
func (e *vcsError) Error() string { | ||
return e.s | ||
} | ||
|
||
// Original retrieves the underlying implementation specific error. | ||
func (e *vcsError) Original() error { | ||
return e.e | ||
} | ||
|
||
// Out retrieves the output of the original command that was run. | ||
func (e *vcsError) Out() string { | ||
return e.o | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package vcs | ||
|
||
import ( | ||
"errors" | ||
"testing" | ||
) | ||
|
||
func TestNewRemoteError(t *testing.T) { | ||
base := errors.New("Foo error") | ||
out := "This is a test" | ||
msg := "remote error msg" | ||
|
||
e := NewRemoteError(msg, base, out) | ||
|
||
switch e.(type) { | ||
case *RemoteError: | ||
// This is the right error type | ||
default: | ||
t.Error("Wrong error type returned from NewRemoteError") | ||
} | ||
} | ||
|
||
func TestNewLocalError(t *testing.T) { | ||
base := errors.New("Foo error") | ||
out := "This is a test" | ||
msg := "local error msg" | ||
|
||
e := NewLocalError(msg, base, out) | ||
|
||
switch e.(type) { | ||
case *LocalError: | ||
// This is the right error type | ||
default: | ||
t.Error("Wrong error type returned from NewLocalError") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not immediately obvious to me where this would be used. I don't remember all the flows exactly, but isn't this the kind of thing where you'd only encounter this if you try to explicitly use the wrong type on an existing on-disk repo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ErrWrongVCS
is an error that exists today. It happens when the type of VCS you already have cloned locally is mismatched with the remote location type. Say the local VCS is bzr and the endpoint is git.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, this did show up in Glide when folks migrated from Google Code (Hg) to GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, totally me just boneheadedly note scrolling far enough down in the diff to see these already existed