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

Handle wrapped errors #1234

Merged
merged 1 commit into from
Apr 26, 2022
Merged

Conversation

illicitonion
Copy link
Contributor

@illicitonion illicitonion commented Apr 12, 2022

What type of PR is this?

Bug fix

What package or component does this PR mostly affect?

language/go

What does this PR do? Why is it needed?

Handle wrapped errors

go mod download returns a different error structure than go list, as
documented at https://go.dev/ref/mod#go-mod-download and https://go.dev/ref/mod#go-list-m

We were previously parsing these assuming they had the same structure,
instead, parse them separately.

Also, prevent infinite looping on invalid JSON.

@achew22
Copy link
Member

achew22 commented Apr 12, 2022

Forgive my naivete on this one, but it seems that you're creating a new struct, which you don't create any instance of, and then call a method on it? Are you depending on struct equivalence to call your unwrap method?

Can we get away with doing a type switch on this to decide if it is an error or string and then put a struct in that has both of those as a fields and returns the one that is non-zero in the Unwrap method?

@illicitonion
Copy link
Contributor Author

We're using Go's built-in json deserialization here: so while we're not manually creating an instance of the jsonError struct, Go is doing so for us. This StackOverflow post suggested that this is the cleanest way to have the json deserializer automatically deserialize either a string or struct.

I don't think here's a handy hook-point where we can insert our own logic here, as we're relying on the stdlib json.Unmarshal, but will gladly restructure if you can nudge me at how :)

@sluongng
Copy link
Contributor

I would suggest adding a test for this change, including an assertion for how go mod download -json outputs would look like if InvalidPathError was to return and how that is failing the decode. Then provide a fix and flip the test assertion.

That would help maintainers review and merge this change a lot easier (without having to go and read up all the link reference).

It's weird how you are experiencing decoding issue since we are essentially following go documentation https://golang.org/ref/mod#go-mod-download here:

> go mod help download
...
The -json flag causes download to print a sequence of JSON objects
to standard output, describing each downloaded module (or failure),
corresponding to this Go struct:

    type Module struct {
        Path     string // module path
        Version  string // module version
        Error    string // error loading module
        Info     string // absolute path to cached .info file
        GoMod    string // absolute path to cached .mod file
        Zip      string // absolute path to cached .zip file
        Dir      string // absolute path to cached source root directory
        Sum      string // checksum for path, version (as in go.sum)
        GoModSum string // checksum for go.mod (as in go.sum)
    }
...

> go version
go version go1.18.1 darwin/arm64

I am still not yet sure on the fix direction just yet, but I can review again once the test is provided.

@illicitonion
Copy link
Contributor Author

Sorry for the incomplete PR - I did some digging, and found that the root cause is actually that we use the same code to parse go list and go mod download output, but they actually use different formats. Added some tests for both cases - PTAL!

Copy link
Contributor

@sluongng sluongng left a comment

Choose a reason for hiding this comment

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

Ah so the output of go mod download and go list are being decoded into type module struct.

And because go list recently updated so we have these differences

// go list
type Module struct {
    ...
    Error      *ModuleError // error loading module
}

// go mod download
type Module struct {
    ...
    Error    string // error loading module
}

hence the proposal is to split module struct into 2 different structs: moduleFromDownload and moduleFromList to avoid decode error. This fix direction LGTM.

language/go/modules.go Outdated Show resolved Hide resolved
language/go/modules.go Show resolved Hide resolved
language/go/modules.go Show resolved Hide resolved
language/go/update_import_test.go Outdated Show resolved Hide resolved
language/go/update_import_test.go Outdated Show resolved Hide resolved
`go mod download` returns a different error structure than `go list`, as
documented at https://go.dev/ref/mod#go-mod-download and https://go.dev/ref/mod#go-list-m

We were previously parsing these assuming they had the same structure,
instead, parse them separately.

Also, prevent infinite looping on invalid JSON.
@illicitonion
Copy link
Contributor Author

All addressed - PTAL

@sluongng
Copy link
Contributor

latest version LGTM

@achew22 could you take a look?

@achew22
Copy link
Member

achew22 commented Apr 26, 2022

This is much cleaner than that was happening before. Thank you for fixing it!

@achew22 achew22 merged commit 56d35f8 into bazel-contrib:master Apr 26, 2022
gcf-merge-on-green bot referenced this pull request in googleapis/gapic-config-validator Jun 27, 2022
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [bazel_gazelle](https://togithub.com/bazelbuild/bazel-gazelle) | http_archive | minor | `v0.25.0` -> `v0.26.0` |

---

### Release Notes

<details>
<summary>bazelbuild/bazel-gazelle</summary>

### [`v0.26.0`](https://togithub.com/bazelbuild/bazel-gazelle/releases/tag/v0.26.0)

[Compare Source](https://togithub.com/bazelbuild/bazel-gazelle/compare/v0.25.0...v0.26.0)

#### What's Changed

-   fix(tests): fix gazelle_generation_test expected stderr update by [@&#8203;jbedard](https://togithub.com/jbedard) in [https://github.com/bazelbuild/bazel-gazelle/pull/1220](https://togithub.com/bazelbuild/bazel-gazelle/pull/1220)
-   Add an e2e test confirming no output on success by [@&#8203;achew22](https://togithub.com/achew22) in [https://github.com/bazelbuild/bazel-gazelle/pull/1216](https://togithub.com/bazelbuild/bazel-gazelle/pull/1216)
-   Update extend.md with a practical languages example by [@&#8203;Anthony-Bible](https://togithub.com/Anthony-Bible) in [https://github.com/bazelbuild/bazel-gazelle/pull/1222](https://togithub.com/bazelbuild/bazel-gazelle/pull/1222)
-   fix: Remove gazelle_binary import collision by [@&#8203;illicitonion](https://togithub.com/illicitonion) in [https://github.com/bazelbuild/bazel-gazelle/pull/1226](https://togithub.com/bazelbuild/bazel-gazelle/pull/1226)
-   Broaden label name regex by [@&#8203;illicitonion](https://togithub.com/illicitonion) in [https://github.com/bazelbuild/bazel-gazelle/pull/1229](https://togithub.com/bazelbuild/bazel-gazelle/pull/1229)
-   gazelle_generation_test: redact workspace path from output by [@&#8203;dr-dime](https://togithub.com/dr-dime) in [https://github.com/bazelbuild/bazel-gazelle/pull/1231](https://togithub.com/bazelbuild/bazel-gazelle/pull/1231)
-   Add -print0 to print names of rewritten files by [@&#8203;dr-dime](https://togithub.com/dr-dime) in [https://github.com/bazelbuild/bazel-gazelle/pull/1213](https://togithub.com/bazelbuild/bazel-gazelle/pull/1213)
-   Code Quality Improvements by [@&#8203;sluongng](https://togithub.com/sluongng) in [https://github.com/bazelbuild/bazel-gazelle/pull/1197](https://togithub.com/bazelbuild/bazel-gazelle/pull/1197)
-   Add -strict to exit on build file and directive errors by [@&#8203;dr-dime](https://togithub.com/dr-dime) in [https://github.com/bazelbuild/bazel-gazelle/pull/1214](https://togithub.com/bazelbuild/bazel-gazelle/pull/1214)
-   fix(lang/proto): include imports from different targets by [@&#8203;nickgooding](https://togithub.com/nickgooding) in [https://github.com/bazelbuild/bazel-gazelle/pull/1237](https://togithub.com/bazelbuild/bazel-gazelle/pull/1237)
-   Update rules example in README to v0.25.0 by [@&#8203;yujunz](https://togithub.com/yujunz) in [https://github.com/bazelbuild/bazel-gazelle/pull/1240](https://togithub.com/bazelbuild/bazel-gazelle/pull/1240)
-   Allow static dependency resolution for Gazelle rule by [@&#8203;uhthomas](https://togithub.com/uhthomas) in [https://github.com/bazelbuild/bazel-gazelle/pull/1242](https://togithub.com/bazelbuild/bazel-gazelle/pull/1242)
-   Handle wrapped errors by [@&#8203;illicitonion](https://togithub.com/illicitonion) in [https://github.com/bazelbuild/bazel-gazelle/pull/1234](https://togithub.com/bazelbuild/bazel-gazelle/pull/1234)
-   Go: Update tests to use cmp.Diff instead of reflect.DeepEqual by [@&#8203;thempatel](https://togithub.com/thempatel) in [https://github.com/bazelbuild/bazel-gazelle/pull/1244](https://togithub.com/bazelbuild/bazel-gazelle/pull/1244)
-   Fix startup script manifest resolution with --nolegacy_external_runfiles by [@&#8203;jvolkman](https://togithub.com/jvolkman) in [https://github.com/bazelbuild/bazel-gazelle/pull/1247](https://togithub.com/bazelbuild/bazel-gazelle/pull/1247)
-   Label's package may contain [@&#8203;s](https://togithub.com/s) by [@&#8203;illicitonion](https://togithub.com/illicitonion) in [https://github.com/bazelbuild/bazel-gazelle/pull/1249](https://togithub.com/bazelbuild/bazel-gazelle/pull/1249)
-   Trim runfiles prefix consistently by [@&#8203;uhthomas](https://togithub.com/uhthomas) in [https://github.com/bazelbuild/bazel-gazelle/pull/1257](https://togithub.com/bazelbuild/bazel-gazelle/pull/1257)
-   Respect .bazelignore by [@&#8203;Whoaa512](https://togithub.com/Whoaa512) in [https://github.com/bazelbuild/bazel-gazelle/pull/1245](https://togithub.com/bazelbuild/bazel-gazelle/pull/1245)
-   Implement very minimalistic support for go workspaces by [@&#8203;HakanSunay](https://togithub.com/HakanSunay) in [https://github.com/bazelbuild/bazel-gazelle/pull/1250](https://togithub.com/bazelbuild/bazel-gazelle/pull/1250)
-   Fix typo in comment by [@&#8203;yujunz](https://togithub.com/yujunz) in [https://github.com/bazelbuild/bazel-gazelle/pull/1270](https://togithub.com/bazelbuild/bazel-gazelle/pull/1270)
-   Use `patch` from `@bazel_tools//tools/build_defs/repo:utils.bzl` by [@&#8203;bozaro](https://togithub.com/bozaro) in [https://github.com/bazelbuild/bazel-gazelle/pull/1269](https://togithub.com/bazelbuild/bazel-gazelle/pull/1269)
-   Update rules_go to 0.33.0 by [@&#8203;fmeum](https://togithub.com/fmeum) in [https://github.com/bazelbuild/bazel-gazelle/pull/1263](https://togithub.com/bazelbuild/bazel-gazelle/pull/1263)
-   Add support for auth_patterns in go_repository by [@&#8203;dmivankov](https://togithub.com/dmivankov) in [https://github.com/bazelbuild/bazel-gazelle/pull/1254](https://togithub.com/bazelbuild/bazel-gazelle/pull/1254)
-   Sluongng/revert patch by [@&#8203;sluongng](https://togithub.com/sluongng) in [https://github.com/bazelbuild/bazel-gazelle/pull/1277](https://togithub.com/bazelbuild/bazel-gazelle/pull/1277)
-   Stop inferring import path for empty packages by [@&#8203;linzhp](https://togithub.com/linzhp) in [https://github.com/bazelbuild/bazel-gazelle/pull/1280](https://togithub.com/bazelbuild/bazel-gazelle/pull/1280)
-   Don't exclude spaces from the label name regex by [@&#8203;illicitonion](https://togithub.com/illicitonion) in [https://github.com/bazelbuild/bazel-gazelle/pull/1271](https://togithub.com/bazelbuild/bazel-gazelle/pull/1271)

#### New Contributors

-   [@&#8203;Anthony-Bible](https://togithub.com/Anthony-Bible) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1222](https://togithub.com/bazelbuild/bazel-gazelle/pull/1222)
-   [@&#8203;dr-dime](https://togithub.com/dr-dime) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1231](https://togithub.com/bazelbuild/bazel-gazelle/pull/1231)
-   [@&#8203;sluongng](https://togithub.com/sluongng) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1197](https://togithub.com/bazelbuild/bazel-gazelle/pull/1197)
-   [@&#8203;nickgooding](https://togithub.com/nickgooding) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1237](https://togithub.com/bazelbuild/bazel-gazelle/pull/1237)
-   [@&#8203;yujunz](https://togithub.com/yujunz) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1240](https://togithub.com/bazelbuild/bazel-gazelle/pull/1240)
-   [@&#8203;uhthomas](https://togithub.com/uhthomas) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1242](https://togithub.com/bazelbuild/bazel-gazelle/pull/1242)
-   [@&#8203;thempatel](https://togithub.com/thempatel) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1244](https://togithub.com/bazelbuild/bazel-gazelle/pull/1244)
-   [@&#8203;Whoaa512](https://togithub.com/Whoaa512) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1245](https://togithub.com/bazelbuild/bazel-gazelle/pull/1245)
-   [@&#8203;HakanSunay](https://togithub.com/HakanSunay) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1250](https://togithub.com/bazelbuild/bazel-gazelle/pull/1250)
-   [@&#8203;bozaro](https://togithub.com/bozaro) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1269](https://togithub.com/bazelbuild/bazel-gazelle/pull/1269)
-   [@&#8203;fmeum](https://togithub.com/fmeum) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1263](https://togithub.com/bazelbuild/bazel-gazelle/pull/1263)
-   [@&#8203;dmivankov](https://togithub.com/dmivankov) made their first contribution in [https://github.com/bazelbuild/bazel-gazelle/pull/1254](https://togithub.com/bazelbuild/bazel-gazelle/pull/1254)

**Full Changelog**: bazel-contrib/bazel-gazelle@v0.25.0...v0.26.0

#### `WORKSPACE` code

    load("@&#8203;bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

    http_archive(
        name = "bazel_gazelle",
        sha256 = "501deb3d5695ab658e82f6f6f549ba681ea3ca2a5fb7911154b5aa45596183fa",
        urls = [
            "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.26.0/bazel-gazelle-v0.26.0.tar.gz",
            "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.26.0/bazel-gazelle-v0.26.0.tar.gz",
        ],
    )

    load("@&#8203;bazel_gazelle//:deps.bzl", "gazelle_dependencies", "go_repository")

    ############################################################

### Define your own dependencies here using go_repository.

### Else, dependencies declared by rules_go/gazelle will be used.

### The first declaration of an external repository "wins".

    ############################################################

    gazelle_dependencies()

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, click this checkbox.

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/gapic-config-validator).
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.

3 participants