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

cli: Don't print help and don't skip defered funcs on failures #2942

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

End-rey
Copy link
Contributor

@End-rey End-rey commented Sep 19, 2024

Closes #623, #2890.

In neofs-cli I add func common.WrapError that wrap error to custom_errors.ExitErr and return it on every error, But I doubt it. Maybe it is necessary to wrap only the first appearance of this error, or vice versa, only the last one.

Copy link

codecov bot commented Sep 19, 2024

Codecov Report

Attention: Patch coverage is 0% with 1433 lines in your changes missing coverage. Please review.

Project coverage is 23.53%. Comparing base (a0447ce) to head (23c2dce).

Files with missing lines Patch % Lines
cmd/neofs-adm/internal/modules/storagecfg/root.go 0.00% 106 Missing ⚠️
cmd/neofs-cli/modules/object/util.go 0.00% 88 Missing ⚠️
cmd/neofs-cli/modules/object/range.go 0.00% 35 Missing ⚠️
cmd/neofs-cli/modules/container/create.go 0.00% 31 Missing ⚠️
cmd/neofs-cli/modules/control/shards_set_mode.go 0.00% 31 Missing ⚠️
cmd/neofs-cli/modules/object/put.go 0.00% 30 Missing ⚠️
cmd/neofs-cli/modules/container/get.go 0.00% 29 Missing ⚠️
cmd/neofs-cli/modules/container/set_eacl.go 0.00% 29 Missing ⚠️
cmd/neofs-cli/modules/storagegroup/put.go 0.00% 29 Missing ⚠️
cmd/neofs-cli/modules/object/get.go 0.00% 28 Missing ⚠️
... and 79 more
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2942      +/-   ##
==========================================
- Coverage   23.88%   23.53%   -0.35%     
==========================================
  Files         776      776              
  Lines       45893    46572     +679     
==========================================
  Hits        10961    10961              
- Misses      34070    34749     +679     
  Partials      862      862              

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

@End-rey End-rey force-pushed the 623-do-not-print-help-on-any-failure branch from 85bf87d to 24ab511 Compare September 19, 2024 08:54
Copy link
Member

@roman-khimov roman-khimov left a comment

Choose a reason for hiding this comment

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

Conflicts, rebase pls. But looks nice in general. Probably we can add some tests for it as well.

//
// 0 if nil
// 1 if [sdkstatus.ErrServerInternal] or untyped
// 2 if [sdkstatus.ErrObjectAccessDenied]
// 3 if [ErrAwaitTimeout]
func ExitOnErr(cmd *cobra.Command, errFmt string, err error) {
func WrapError(errFmt string, err error) *custom_errors.ExitErr {
Copy link
Member

Choose a reason for hiding this comment

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

I'd probably do it as WrapError(err error) and leave fmt.Errorf() to the caller if and when needed. You still can unwrap internally to get the code, but formatting would be easier, I think. You can have cases like "smth (additional data: %d): %w" and this won't fit the current interface.

@@ -9,9 +9,11 @@ Changelog for NeoFS Node
- Expose health status of inner ring via Prometheus (#2934)

### Fixed
- `defer` func is not skipped in cobra-based programs (#2942)
Copy link
Member

Choose a reason for hiding this comment

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

Not sure it makes sense for outside reader, but don't have immediate suggestions either.

Copy link
Contributor

@cthulhu-rider cthulhu-rider left a comment

Choose a reason for hiding this comment

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

in total, lux gut

afaik #623 can be resolved purely independent, so its better to dedicate a separate small (last) commit for it to not mix with heavy #2890.

also tag intermediate commits with Refs #2890.

@@ -0,0 +1,27 @@
package custom_errors
Copy link
Contributor

Choose a reason for hiding this comment

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

not a good choice of pkg name https://go.dev/blog/package-names. I can suggest cmderr

if getConfirmation(false, "Continue configuration? yes/[no]: ") {
return
if flag, err := getConfirmation(false, "Continue configuration? yes/[no]: "); flag {
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

this never happens for flag==true, i think the condition should be

if flag, err := getConfirmation(false, "Continue configuration? yes/[no]: "); flag || err != nil {
	return err
}

//
// 0 if nil
// 1 if [sdkstatus.ErrServerInternal] or untyped
// 2 if [sdkstatus.ErrObjectAccessDenied]
// 3 if [ErrAwaitTimeout]
func ExitOnErr(cmd *cobra.Command, errFmt string, err error) {
func WrapError(errFmt string, err error) *custom_errors.ExitErr {
Copy link
Contributor

Choose a reason for hiding this comment

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

it should not return pointers to be compliant with ExitOnErr making

var e ExitErr
if !errors.As(err, &e) {
	e.Code = 1
}

easy to check

func TestExit(t *testing.T) {
	custom_errors.ExitOnErr(common.WrapError("context; %w", common.ErrAwaitTimeout))
}

expected 3, got 1

cli, err := getSDKClientByFlag(ctx, endpointFlag)
if err != nil {
common.ExitOnErr(cmd, "can't create API client: %w", err)
return nil, common.WrapError("can't create API client: %w", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

i dont think this is a good place to throw ExitErr, this is the responsibility of RunEs. So, just return nil, fmt.Errorf(...)

}

var exitErr *custom_errors.ExitErr
if errors.As(err, &exitErr) {
Copy link
Contributor

Choose a reason for hiding this comment

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

having this means that code does not care who makes ExitErr while it should. Imo normally this should never be true. The most stable approach is to wrap by RunE functions only

_, err := os.Stat(eaclPath) // check if `eaclPath` is an existing file
if err != nil {
ExitOnErr(cmd, "", errors.New("incorrect path to file with EACL"))
return eacl.Table{}, WrapError("", errors.New("incorrect path to file with EACL"))
Copy link
Contributor

Choose a reason for hiding this comment

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

here too enough to return eacl.Table{}, errors.New("incorrect path to file with EACL") and let caller how to wrap it. With this, u wont need to wrap all function returns

var addr oid.Address

err := addr.DecodeString(vAddress)
common.ExitOnErr(cmd, common.Errf("invalid address argument: %w", err))
if err != nil {
return common.Errf("invalid address argument: %w", err)
Copy link
Contributor

Choose a reason for hiding this comment

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

common.Errf made sense with ExitOnErr func since it allowed to avoid if statement. Now we should use fmt.Errorf (and purge Errf)

@End-rey End-rey marked this pull request as draft September 20, 2024 07:02
@End-rey End-rey force-pushed the 623-do-not-print-help-on-any-failure branch from 24ab511 to b99e708 Compare September 23, 2024 16:03
For all cobra-based programs add custom error with code and cause of error and
exit func from programs.

Signed-off-by: Andrey Butusov <andrey@nspcc.io>
Use `RunE` instead of `Run` and throw an error to main function. Then handle
error with custom error handler.

Signed-off-by: Andrey Butusov <andrey@nspcc.io>
Use `RunE` instead of `Run` and throw an error to main function. Wrap error with
`common.WrapError` to specify the status code. Then handle error with custom
error handler.

Signed-off-by: Andrey Butusov <andrey@nspcc.io>
Use `RunE` instead of `Run` and throw an error to main function. Then handle
error with custom error handler.
Update CHANGELOG.md.

Closes #2890.

Signed-off-by: Andrey Butusov <andrey@nspcc.io>
Closes #623.
Refs #2890.

Signed-off-by: Andrey Butusov <andrey@nspcc.io>
@End-rey End-rey force-pushed the 623-do-not-print-help-on-any-failure branch from b99e708 to 23c2dce Compare September 23, 2024 16:05
@End-rey End-rey marked this pull request as ready for review September 23, 2024 16:17
@End-rey
Copy link
Contributor Author

End-rey commented Sep 23, 2024

Now, in the neofs-cli, func common.WrapError is used after receiving the cobra command error in main.

"os"
)

type ExitErr struct {
Copy link
Member

Choose a reason for hiding this comment

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

an exported type, should be documented according to ancient chronicles

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.

cli: Do not print help on any failure
4 participants