{"record":{"id":"392ff8f6e0f25611","repo":"GoogleCloudPlatform/microservices-demo","slug":"unexpected-status-code-d","errorCode":null,"errorMessage":"Unexpected status code: %d","messagePattern":"Unexpected status code: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/frontend/packaging_info.go","lineNumber":62,"sourceCode":"}\n\nfunc isPackagingServiceConfigured() bool {\n\treturn packagingServiceUrl != \"\"\n}\n\nfunc httpGetPackagingInfo(productId string) (*PackagingInfo, error) {\n\t// Make the GET request\n\turl := packagingServiceUrl + \"/\" + productId\n\tfmt.Println(\"Requesting packaging info from URL: \", url)\n\tresp, err := http.Get(url)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer resp.Body.Close()\n\n\t// Check the response status code\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn nil, fmt.Errorf(\"Unexpected status code: %d\", resp.StatusCode)\n\t}\n\n\t// Read the JSON response body\n\tresponseBody, err := ioutil.ReadAll(resp.Body)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\t// Decode the JSON response into a PackagingInfo struct\n\tvar packagingInfo PackagingInfo\n\terr = json.Unmarshal(responseBody, &packagingInfo)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &packagingInfo, nil\n}\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/GoogleCloudPlatform/microservices-demo/blob/72ba613a05f7fcee51cf1d0badff401b6ae7074d/src/frontend/packaging_info.go#L44-L80","documentation":"httpGetPackagingInfo calls an HTTP endpoint (packaging info service) and checks the response status. If the status is anything other than 200 OK, it returns fmt.Errorf(\"Unexpected status code: %d\", resp.StatusCode). This library throws it to surface upstream HTTP failures (404, 500, 503, etc.) instead of trying to parse a non-JSON body.","triggerScenarios":"Any non-200 HTTP response from the packaging info backend: client.Get succeeds at the transport level but the server replies with 404 (wrong path), 500 (backend error), 401/403, or 503.","commonSituations":"Packaging service URL misconfigured via env var; service deployed at a different route prefix; backend crash-looping returning 503; auth proxy stripping/injecting headers causing 403; product page load showing 500 to end users.","solutions":["Log/inspect the actual status code and response body to identify which non-200 was returned","Verify the packaging info service URL/route configuration is correct","Check the packaging service health — restart or scale it if returning 5xx","Confirm auth/network policies allow the frontend to reach the endpoint","Consider tolerating missing packaging info (log and degrade) instead of failing the whole product page"],"exampleFix":"// before\nreturn nil, fmt.Errorf(\"Unexpected status code: %d\", resp.StatusCode)\n// after\nbody, _ := ioutil.ReadAll(resp.Body)\nreturn nil, fmt.Errorf(\"packaging info request failed: status=%d body=%q\", resp.StatusCode, string(body))","handlingStrategy":"fallback","validationCode":"req, err := http.NewRequestWithContext(ctx, http.MethodGet, packagingInfoURL, nil)\nif err != nil || packagingInfoURL == \"\" {\n    return nil, fmt.Errorf(\"invalid packaging info URL: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"info, err := httpGetPackagingInfo(ctx, client, productID)\nif err != nil {\n    var statusErr *statusCodeError\n    if errors.As(err, &statusErr) && statusErr.code >= 500 {\n        info = defaultPackagingInfo // degrade gracefully\n    } else {\n        return err\n    }\n}","preventionTips":["Check resp.StatusCode and log the body for every non-200","Verify packaging service URL configuration at startup","Add health/readiness checks for the packaging endpoint","Degrade gracefully when packaging info is optional"],"tags":["http","golang","frontend","status-code"],"backgroundTag":"unexpected-http-status-code","analyzedSha":"72ba613a05f7fcee51cf1d0badff401b6ae7074d","analyzedAt":"2026-09-02T01:15:09.673Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}