diff --git a/diff/diff_error_test.go b/diff/diff_error_test.go index 08c375a5..babb8baa 100644 --- a/diff/diff_error_test.go +++ b/diff/diff_error_test.go @@ -240,5 +240,5 @@ func TestDiff_ComponentCallbacksNil(t *testing.T) { func TestFilterByRegex_Invalid(t *testing.T) { _, err := diff.Get(&diff.Config{PathFilter: "["}, l(t, 1), l(t, 2)) - require.EqualError(t, err, "failed to compile filter regex \"[\" with error parsing regexp: missing closing ]: `[`") + require.EqualError(t, err, "failed to compile filter regex \"[\": error parsing regexp: missing closing ]: `[`") } diff --git a/diff/example_test.go b/diff/example_test.go index b04eae8c..58f8d496 100644 --- a/diff/example_test.go +++ b/diff/example_test.go @@ -18,13 +18,13 @@ func ExampleGet() { s1, err := loader.LoadFromFile("../data/simple1.yaml") if err != nil { - fmt.Fprintf(os.Stderr, "failed to load spec with %v", err) + fmt.Fprintf(os.Stderr, "failed to load spec: %v", err) return } s2, err := loader.LoadFromFile("../data/simple2.yaml") if err != nil { - fmt.Fprintf(os.Stderr, "failed to load spec with %v", err) + fmt.Fprintf(os.Stderr, "failed to load spec: %v", err) return } @@ -66,13 +66,13 @@ func ExampleGetPathsDiff() { s1, err := load.NewSpecInfo(loader, load.NewSource("../data/openapi-test1.yaml")) if err != nil { - fmt.Fprintf(os.Stderr, "failed to load spec with %v", err) + fmt.Fprintf(os.Stderr, "failed to load spec: %v", err) return } s2, err := load.NewSpecInfo(loader, load.NewSource("../data/openapi-test3.yaml")) if err != nil { - fmt.Fprintf(os.Stderr, "failed to load spec with %v", err) + fmt.Fprintf(os.Stderr, "failed to load spec: %v", err) return } diff --git a/diff/operations_diff.go b/diff/operations_diff.go index d0f4ba9e..e053c89c 100644 --- a/diff/operations_diff.go +++ b/diff/operations_diff.go @@ -130,7 +130,7 @@ func filterOperationsByExtensions(filterExtension string, pathItemPair *pathItem r, err := regexp.Compile(filterExtension) if err != nil { - return fmt.Errorf("failed to compile extension filter regex %q with %w", filterExtension, err) + return fmt.Errorf("failed to compile extension filter regex %q: %w", filterExtension, err) } filterOperationsByExtensionInternal(pathItemPair.PathItem1, r) diff --git a/diff/paths_diff.go b/diff/paths_diff.go index b038a517..8678dc45 100644 --- a/diff/paths_diff.go +++ b/diff/paths_diff.go @@ -123,7 +123,7 @@ func filterPathsByName(filter string, paths1, paths2 *openapi3.Paths) error { r, err := regexp.Compile(filter) if err != nil { - return fmt.Errorf("failed to compile filter regex %q with %w", filter, err) + return fmt.Errorf("failed to compile filter regex %q: %w", filter, err) } filterPathsInternal(paths1, r) @@ -147,7 +147,7 @@ func filterPathsByExtensions(filterExtension string, paths1, paths2 *openapi3.Pa r, err := regexp.Compile(filterExtension) if err != nil { - return fmt.Errorf("failed to compile extension filter regex %q with %w", filterExtension, err) + return fmt.Errorf("failed to compile extension filter regex %q: %w", filterExtension, err) } filterPathsByExtensionInternal(paths1, r) diff --git a/flatten/allof/merge_allof_spec_test.go b/flatten/allof/merge_allof_spec_test.go index 4b0bd787..48fff4f7 100644 --- a/flatten/allof/merge_allof_spec_test.go +++ b/flatten/allof/merge_allof_spec_test.go @@ -24,5 +24,5 @@ func Test_MergeSpecOK(t *testing.T) { func Test_MergeSpecInvalid(t *testing.T) { _, err := load.NewSpecInfo(openapi3.NewLoader(), load.NewSource("../../data/allof/invalid.yaml"), load.WithFlattenAllOf()) - require.EqualError(t, err, "unable to resolve Type conflict: all Type values must be identical") + require.EqualError(t, err, "failed to flatten allOf in \"../../data/allof/invalid.yaml\": unable to resolve Type conflict: all Type values must be identical") } diff --git a/internal/errors.go b/internal/errors.go index 322aea01..190c4cbe 100644 --- a/internal/errors.go +++ b/internal/errors.go @@ -22,28 +22,28 @@ func getErrInvalidFlags(err error) *ReturnError { func getErrFailedToLoadSpec(what string, source *load.Source, err error) *ReturnError { return getError( - fmt.Errorf("failed to load %s spec from %s with %v", what, source.Out(), err), + fmt.Errorf("failed to load %s spec from %s: %w", what, source.Out(), err), 102, ) } func getErrFailedToLoadSpecs(what string, path string, err error) *ReturnError { return getError( - fmt.Errorf("failed to load %s specs from glob %q with %v", what, path, err), + fmt.Errorf("failed to load %s specs from glob %q: %w", what, path, err), 103, ) } func getErrDiffFailed(err error) *ReturnError { return getError( - fmt.Errorf("diff failed with %v", err), + fmt.Errorf("diff failed: %w", err), 104, ) } func getErrFailedPrint(what string, err error) *ReturnError { return getError( - fmt.Errorf("failed to print %q with %v", what, err), + fmt.Errorf("failed to print %q: %w", what, err), 105, ) } @@ -92,7 +92,7 @@ func getErrInvalidColorMode(err error) *ReturnError { func getErrCantProcessIgnoreFile(what string, err error) *ReturnError { return getError( - fmt.Errorf("can't process %s ignore file %v", what, err), + fmt.Errorf("can't process %s ignore file: %w", what, err), 121, ) } diff --git a/internal/run_test.go b/internal/run_test.go index f1f7d826..144afe90 100644 --- a/internal/run_test.go +++ b/internal/run_test.go @@ -78,27 +78,27 @@ func Test_InvalidFile(t *testing.T) { var stderr bytes.Buffer require.Equal(t, 102, internal.Run(cmdToArgs("oasdiff diff no-file ../data/openapi-test3.yaml"), io.Discard, &stderr)) require.Condition(t, func() (success bool) { - return stderr.String() == "Error: failed to load base spec from \"no-file\" with open no-file: no such file or directory\n" || - stderr.String() == "Error: failed to load base spec from \"no-file\" with open no-file: The system cannot find the file specified.\n" // windows - }) + return stderr.String() == "Error: failed to load base spec from \"no-file\": open no-file: no such file or directory\n" || + stderr.String() == "Error: failed to load base spec from \"no-file\": open no-file: The system cannot find the file specified.\n" // windows + }, stderr.String()) } func Test_InvalidGlob(t *testing.T) { var stderr bytes.Buffer require.Equal(t, 103, internal.Run(cmdToArgs(`oasdiff diff -c "a[" ../data/openapi-test3.yaml`), io.Discard, &stderr)) - require.Equal(t, "Error: failed to load base specs from glob \"\\\"a[\\\"\" with syntax error in pattern\n", stderr.String()) + require.Equal(t, "Error: failed to load base specs from glob \"\\\"a[\\\"\": syntax error in pattern\n", stderr.String()) } func Test_GlobNoFiles(t *testing.T) { var stderr bytes.Buffer require.Equal(t, 103, internal.Run(cmdToArgs("oasdiff diff -c no-file ../data/openapi-test3.yaml"), io.Discard, &stderr)) - require.Equal(t, "Error: failed to load base specs from glob \"no-file\" with no matching files\n", stderr.String()) + require.Equal(t, "Error: failed to load base specs from glob \"no-file\": no matching files\n", stderr.String()) } func Test_GlobWithUrl(t *testing.T) { var stderr bytes.Buffer require.Equal(t, 103, internal.Run(cmdToArgs("oasdiff diff -c ../data/openapi-test1.yaml https://"), io.Discard, &stderr)) - require.Equal(t, "Error: failed to load revision specs from glob \"https://\" with no matching files (should be a glob, not a URL)\n", stderr.String()) + require.Equal(t, "Error: failed to load revision specs from glob \"https://\": no matching files (should be a glob, not a URL)\n", stderr.String()) } func Test_DiffInvalidFormat(t *testing.T) { @@ -202,6 +202,13 @@ func Test_ComposedMode(t *testing.T) { require.Equal(t, map[string]interface{}{"paths": map[string]interface{}{"deleted": []interface{}{"/api/old-test"}}}, bc) } +func Test_ComposedModeInvalidFile(t *testing.T) { + var stderr bytes.Buffer + require.Equal(t, 103, internal.Run(cmdToArgs("oasdiff diff ../data/allof/* ../data/allof/* --composed --flatten"), io.Discard, &stderr)) + require.Equal(t, `Error: failed to load base specs from glob "../data/allof/*": failed to flatten allOf in "../data/allof/invalid.yaml": unable to resolve Type conflict: all Type values must be identical +`, stderr.String()) +} + func Test_Help(t *testing.T) { var stdout bytes.Buffer require.Zero(t, internal.Run(cmdToArgs("oasdiff --help"), &stdout, io.Discard)) @@ -285,7 +292,7 @@ func Test_FlattenCmdOK(t *testing.T) { func Test_FlattenCmdInvalid(t *testing.T) { var stderr bytes.Buffer require.Equal(t, 102, internal.Run(cmdToArgs("oasdiff flatten ../data/allof/invalid.yaml"), io.Discard, &stderr)) - require.Equal(t, `Error: failed to load original spec from "../data/allof/invalid.yaml" with unable to resolve Type conflict: all Type values must be identical + require.Equal(t, `Error: failed to load original spec from "../data/allof/invalid.yaml": failed to flatten allOf in "../data/allof/invalid.yaml": unable to resolve Type conflict: all Type values must be identical `, stderr.String()) } diff --git a/load/option.go b/load/option.go index bc408ae3..bcaaa1b4 100644 --- a/load/option.go +++ b/load/option.go @@ -1,6 +1,8 @@ package load import ( + "fmt" + "github.com/tufin/oasdiff/flatten/allof" "github.com/tufin/oasdiff/flatten/commonparams" "github.com/tufin/oasdiff/flatten/headers" @@ -30,7 +32,7 @@ func WithFlattenAllOf() Option { var err error for _, specInfo := range specInfos { if specInfo.Spec, err = allof.MergeSpec(specInfo.Spec); err != nil { - return nil, err + return nil, fmt.Errorf("failed to flatten allOf in %q: %w", specInfo.Url, err) } } return specInfos, nil diff --git a/load/spec_info.go b/load/spec_info.go index f1f57b58..01710fe4 100644 --- a/load/spec_info.go +++ b/load/spec_info.go @@ -2,6 +2,7 @@ package load import ( "errors" + "fmt" "net/url" "github.com/getkin/kin-openapi/openapi3" @@ -86,7 +87,7 @@ func fromGlob(loader Loader, glob string) ([]*SpecInfo, error) { for _, file := range files { spec, err := loader.LoadFromFile(file) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to load %q: %w", file, err) } result = append(result, &SpecInfo{Url: file, Spec: spec}) } diff --git a/load/spec_info_test.go b/load/spec_info_test.go index de7e90c0..77c77627 100644 --- a/load/spec_info_test.go +++ b/load/spec_info_test.go @@ -111,7 +111,7 @@ func TestSpecInfo_GlobOK(t *testing.T) { func TestSpecInfo_InvalidSpec(t *testing.T) { _, err := load.NewSpecInfoFromGlob(MockLoader{}, "../data/ignore-err-example.txt") - require.EqualError(t, err, "error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type openapi3.TBis") + require.EqualError(t, err, "failed to load \"../data/ignore-err-example.txt\": error unmarshaling JSON: while decoding JSON: json: cannot unmarshal string into Go value of type openapi3.TBis") } func TestSpecInfo_InvalidGlob(t *testing.T) {