From 3d03233b16d42450d1deb4b9f2aa18a837cc0f6c Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Tue, 11 Mar 2025 17:32:24 +1100 Subject: [PATCH] refactor: ParseError can carry an exit code Reinstated use of ParseError for all error paths so as to retain existing semantics. --- error.go | 10 ++++++++-- kong.go | 22 +++++++++++----------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/error.go b/error.go index 33a4e14..e79a15d 100644 --- a/error.go +++ b/error.go @@ -5,11 +5,17 @@ package kong // It contains the parse Context that triggered the error. type ParseError struct { error - Context *Context + Context *Context + exitCode int } // Unwrap returns the original cause of the error. func (p *ParseError) Unwrap() error { return p.error } // ExitCode returns the status that Kong should exit with if it fails with a ParseError. -func (p *ParseError) ExitCode() int { return exitUsageError } +func (p *ParseError) ExitCode() int { + if p.exitCode == 0 { + return exitNotOk + } + return p.exitCode +} diff --git a/kong.go b/kong.go index e000553..4f6be87 100644 --- a/kong.go +++ b/kong.go @@ -312,34 +312,34 @@ func (k *Kong) extraFlags() []*Flag { func (k *Kong) Parse(args []string) (ctx *Context, err error) { ctx, err = Trace(k, args) if err != nil { // Trace is not expected to return an err - return nil, err + return nil, &ParseError{error: err, Context: ctx, exitCode: exitUsageError} } if ctx.Error != nil { - return nil, &ParseError{error: ctx.Error, Context: ctx} + return nil, &ParseError{error: ctx.Error, Context: ctx, exitCode: exitUsageError} } if err = k.applyHook(ctx, "BeforeReset"); err != nil { - return nil, err + return nil, &ParseError{error: err, Context: ctx} } if err = ctx.Reset(); err != nil { return nil, &ParseError{error: err, Context: ctx} } if err = k.applyHook(ctx, "BeforeResolve"); err != nil { - return nil, err + return nil, &ParseError{error: err, Context: ctx} } if err = ctx.Resolve(); err != nil { return nil, &ParseError{error: err, Context: ctx} } if err = k.applyHook(ctx, "BeforeApply"); err != nil { - return nil, err - } - if _, err = ctx.Apply(); err != nil { // Apply is not expected to return an err - return nil, err - } - if err = ctx.Validate(); err != nil { return nil, &ParseError{error: err, Context: ctx} } + if _, err = ctx.Apply(); err != nil { // Apply is not expected to return an err + return nil, &ParseError{error: err, Context: ctx} + } + if err = ctx.Validate(); err != nil { + return nil, &ParseError{error: err, Context: ctx, exitCode: exitUsageError} + } if err = k.applyHook(ctx, "AfterApply"); err != nil { - return nil, err + return nil, &ParseError{error: err, Context: ctx} } return ctx, nil }