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

feat: join error #26

Merged
merged 4 commits into from
Jun 13, 2024
Merged

feat: join error #26

merged 4 commits into from
Jun 13, 2024

Conversation

Gogomoe
Copy link
Collaborator

@Gogomoe Gogomoe commented Jun 7, 2024

What's changed and what's your intention?

resolve #22
eris.Join(err...) almost is eris.Wrap(errors.Join(err...), "join error")
Implementing and testing the format is a bit hard.
the format looks like:

// no trace text
code(internal) outer wrap: code(unknown) join error
0>	fmt error
1>	code(internal) wrap1: code(internal) wrap2: external
2>	code(unknown) eris error
// trace text
code(internal) outer wrap
	eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:22
code(unknown) join error
	eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:22
	eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:17
0>	fmt error
1>	code(internal) wrap1
		eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:19
	code(internal) wrap2
		eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:19
		eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:19
	external
2>	code(unknown) eris error
		eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:20
// no trace json
{
	"externals": [
		{
			"external": "fmt error"
		},
		{
			"external": "external",
			"root": {
				"code": "internal",
				"message": "wrap2"
			},
			"wrap": [
				{
					"code": "internal",
					"message": "wrap1"
				}
			]
		},
		{
			"root": {
				"code": "unknown",
				"message": "eris error"
			}
		}
	],
	"root": {
		"code": "unknown",
		"message": "join error"
	},
	"wrap": [
		{
			"code": "internal",
			"message": "outer wrap"
		}
	]
}
// trace json
{
	"externals": [
		{
			"external": "fmt error"
		},
		{
			"external": "external",
			"root": {
				"code": "internal",
				"message": "wrap2",
				"stack": [
					"eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:19",
					"eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:19"
				]
			},
			"wrap": [
				{
					"code": "internal",
					"message": "wrap1",
					"stack": "eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:19"
				}
			]
		},
		{
			"root": {
				"code": "unknown",
				"message": "eris error",
				"stack": [
					"eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:20"
				]
			}
		}
	],
	"root": {
		"code": "unknown",
		"message": "join error",
		"stack": [
			"eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:22",
			"eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:17"
		]
	},
	"wrap": [
		{
			"code": "internal",
			"message": "outer wrap",
			"stack": "eris_test.TestName:/Users/gogo/workspace/eris/a_test.go:22"
		}
	]
}

Checklist

  • I have written the necessary docs and comments
  • I have added necessary unit tests and integration tests

Refer to a related PR or issue link (optional)

Close #22

@Gogomoe Gogomoe requested review from CAJan93 and wjf3121 June 7, 2024 07:06
Copy link

codecov bot commented Jun 7, 2024

Codecov Report

Attention: Patch coverage is 91.89189% with 3 lines in your changes missing coverage. Please review.

Project coverage is 86.51%. Comparing base (e59a5ad) to head (4812207).

Files Patch % Lines
format.go 90.62% 1 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #26      +/-   ##
==========================================
+ Coverage   86.33%   86.51%   +0.18%     
==========================================
  Files           4        4              
  Lines         556      586      +30     
==========================================
+ Hits          480      507      +27     
- Misses         72       73       +1     
- Partials        4        6       +2     
Flag Coverage Δ
unittests 86.51% <91.89%> (+0.18%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.


// Join returns an error that wraps the given errors.
func Join(errs ...error) error {
internal := errors.Join(errs...)
Copy link
Contributor

Choose a reason for hiding this comment

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

This will break eris.Is's behavior, which I'm not so sure.

Caller can be easily mistaken and make the wrong assumption.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should for sure test that eris.Is still works with this implementation

First simple test in #28 shows that it still seems to work. In the end we inherit the behaviour of errors.Join

I did not want to push into your branch, that is why I created the tiny PR @Gogomoe

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sorry i forget to reply the comment. The eris.is and as are implemented in #27. I also added more testcases to cover the join error

@CAJan93
Copy link
Collaborator

CAJan93 commented Jun 10, 2024

@Gogomoe out of curiosity. What would you like to use eris.Join for? To me the idiomatic way to handle go errors is

value, err := someFunc(input)
if err != nil {
   // wrap err and return
}

When do we want to join? The only things that I can think about are

  • validating something, e.g. user input, and returning an all the found errors
  • doing multiple tasks concurrently, waiting until all tasks are done, and then joining the errors.

@Gogomoe
Copy link
Collaborator Author

Gogomoe commented Jun 10, 2024

@Gogomoe out of curiosity. What would you like to use eris.Join for? To me the idiomatic way to handle go errors is

Another situation is retry an action for mutiple times. It's a common pattern used in our code base. I dont' want to ignore any error when all retry fails. Currently, we use errors.join in this case. You can check the use case by searching it in our code base

Copy link
Contributor

@wjf3121 wjf3121 left a comment

Choose a reason for hiding this comment

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

LGTM!

t.Errorf("%v: expected { %v } got { %v }", desc, tt.wrapOutput[i]["message"], wrapMap[i]["message"])
}
if _, exists := wrapMap[i]["stack"]; tt.withTrace && !exists {
t.Fatalf("%v: expected a 'stack' field in the output but didn't find one { %v }", desc, errJSON)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I suppose this can be t.Errorf as we can still check the rest of the wrapError in the loop.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I copied the wrapMap section from other test cases. Leet's keep it 🤪

@Gogomoe
Copy link
Collaborator Author

Gogomoe commented Jun 12, 2024

I plan to merge this PR tomorrow. @CAJan93 Do you have more opinions about this PR?

@Gogomoe Gogomoe merged commit c2b8c9a into main Jun 13, 2024
4 checks passed
@Gogomoe Gogomoe deleted the chuan/join_error branch June 13, 2024 05:33
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.

feat: support Join
3 participants