Repository: getkin/kin-openapi
Pull request #348 (2021-04-23 18:09:24)

[Bugfix] fixed error message when only file is referenced
@fenollp you were right: The error should include the location. The problem is, that the handling is different if the reference is just a file without a reference (\#....). I added a test case for that and aligned the error message.


Patch:
diff --git a/openapi3/swagger_loader.go b/openapi3/swagger_loader.go
index 65904d7..eaaf9bd 100644
--- a/openapi3/swagger_loader.go
+++ b/openapi3/swagger_loader.go
@@ -126,7 +126,7 @@ func (swaggerLoader *SwaggerLoader) readURL(location *url.URL) ([]byte, error) {
 		}
 		defer resp.Body.Close()
 		if resp.StatusCode > 399 {
-			return nil, fmt.Errorf("request returned status code %d", resp.StatusCode)
+			return nil, fmt.Errorf("error loading %q: request returned status code %d", location.String(), resp.StatusCode)
 		}
 		return ioutil.ReadAll(resp.Body)
 	}


Test patch:
diff --git a/openapi3/swagger_loader_http_error_test.go b/openapi3/swagger_loader_http_error_test.go
index 3b3d06c..ba361f4 100644
--- a/openapi3/swagger_loader_http_error_test.go
+++ b/openapi3/swagger_loader_http_error_test.go
@@ -10,7 +10,7 @@ import (
 	"github.com/stretchr/testify/require"
 )
 
-func TestLoadFromRemoteURLFailsWithHttpError(t *testing.T) {
+func TestLoadReferenceFromRemoteURLFailsWithHttpError(t *testing.T) {
 	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		w.WriteHeader(http.StatusBadRequest)
 		fmt.Fprint(w, "")
@@ -47,9 +47,53 @@ func TestLoadFromRemoteURLFailsWithHttpError(t *testing.T) {
 	swagger, err := loader.LoadSwaggerFromDataWithPath(spec, &url.URL{Path: "testdata/testfilename.openapi.json"})
 
 	require.Nil(t, swagger)
-	require.EqualError(t, err, fmt.Sprintf("error resolving reference \"%s/components.openapi.json#/components/headers/CustomTestHeader\": request returned status code 400", ts.URL))
+	require.EqualError(t, err, fmt.Sprintf("error resolving reference \"%s/components.openapi.json#/components/headers/CustomTestHeader\": error loading \"%s/components.openapi.json\": request returned status code 400", ts.URL, ts.URL))
+
+	swagger, err = loader.LoadSwaggerFromData(spec)
+	require.Nil(t, swagger)
+	require.EqualError(t, err, fmt.Sprintf("error resolving reference \"%s/components.openapi.json#/components/headers/CustomTestHeader\": error loading \"%s/components.openapi.json\": request returned status code 400", ts.URL, ts.URL))
+}
+
+func TestLoadFromRemoteURLFailsWithHttpError(t *testing.T) {
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.WriteHeader(http.StatusBadRequest)
+		fmt.Fprint(w, "")
+	}))
+	defer ts.Close()
+
+	spec := []byte(`
+{
+    "openapi": "3.0.0",
+    "info": {
+        "title": "",
+        "version": "1"
+    },
+    "paths": {
+        "/test": {
+            "post": {
+                "responses": {
+                    "default": {
+                        "description": "test",
+                        "headers": {
+                            "X-TEST-HEADER": {
+                                "$ref": "` + ts.URL + `/components.openapi.json"
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}`)
+
+	loader := NewSwaggerLoader()
+	loader.IsExternalRefsAllowed = true
+	swagger, err := loader.LoadSwaggerFromDataWithPath(spec, &url.URL{Path: "testdata/testfilename.openapi.json"})
+
+	require.Nil(t, swagger)
+	require.EqualError(t, err, fmt.Sprintf("error loading \"%s/components.openapi.json\": request returned status code 400", ts.URL))
 
 	swagger, err = loader.LoadSwaggerFromData(spec)
 	require.Nil(t, swagger)
-	require.EqualError(t, err, fmt.Sprintf("error resolving reference \"%s/components.openapi.json#/components/headers/CustomTestHeader\": request returned status code 400", ts.URL))
+	require.EqualError(t, err, fmt.Sprintf("error loading \"%s/components.openapi.json\": request returned status code 400", ts.URL))
 }