{"record":{"id":"8d9934cd24514740","repo":"wtfutil/wtf","slug":"s-8d9934","errorCode":null,"errorMessage":"%s","messagePattern":"%s","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/weatherservices/arpansagovau/client.go","lineNumber":71,"sourceCode":"}\n\n/* -------------------- Unexported Functions -------------------- */\n\nfunc apiRequest() (*http.Response, error) {\n\treq, err := http.NewRequest(\"GET\", \"https://uvdata.arpansa.gov.au/xml/uvvalues.xml\", http.NoBody)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\thttpClient := &http.Client{}\n\tresp, err := httpClient.Do(req)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\tif resp.StatusCode != 200 {\n\t\treturn nil, fmt.Errorf(\"%s\", resp.Status)\n\t}\n\n\treturn resp, nil\n}\nfunc parseXML(text io.Reader) (Stations, error) {\n\tdec := xml.NewDecoder(text)\n\tdec.Strict = false\n\n\tvar v Stations\n\terr := dec.Decode(&v)\n\treturn v, err\n}\n","sourceCodeStart":53,"sourceCodeEnd":84,"githubUrl":"https://github.com/wtfutil/wtf/blob/bb838c1ccb0f0f3223690df44afdec663d622881/modules/weatherservices/arpansagovau/client.go#L53-L84","documentation":"apiRequest in the Australian BOM (arpansagovau weather) widget returns fmt.Errorf(\"%s\", resp.Status) when the BOM/ARPANSA HTTP response status is not 200. The error message is the raw HTTP status line (e.g. '404 Not Found' or '503 Service Unavailable'). The upstream call errors are otherwise passed through unchanged.","triggerScenarios":"getLocationData → apiRequest performs the HTTP GET; the server responds with any non-200 code — 404 if the station/observation URL path changed, 403 for blocked requests, 5xx or 503 during BOM service disruptions.","commonSituations":"BOM changes or retires observation endpoints/IDs, station identifier in config is wrong, network middleboxes (proxies, geo-blocks) returning 403, BOM outages.","solutions":["Check the status line in the message: 404 → verify the station ID/URL against the current BOM API endpoints","Confirm the location/station configuration value matches a valid BOM observation identifier","Test the URL directly with curl or a browser to see whether the endpoint still serves data","For 5xx/503, retry later — ARPANSA/BOM outages are transient"],"exampleFix":"// before\nstation: \"IDS60901\" // retired ID\n// after\nstation: \"IDS60902\" // current BOM station ID","handlingStrategy":"retry","validationCode":"resp, err := http.Get(bomURL)\nif err != nil { return err }\nif resp.StatusCode != 200 {\n    return fmt.Errorf(\"BOM endpoint unhealthy: %s\", resp.Status)\n}\nresp.Body.Close()","typeGuard":null,"tryCatchPattern":"data, err := w.getLocationData()\nif err != nil {\n    log.Printf(\"BOM fetch failed (%v); retrying with backoff\", err)\n    select {\n    case <-time.After(30 * time.Second):\n        data, err = w.getLocationData()\n    case <-ctx.Done():\n        return ctx.Err()\n    }\n}","preventionTips":["Pin/verify station IDs against the current BOM endpoint list","Expect BOM outages and add caching of last-good data","Test the observation URL in a browser when configuring a new station"],"tags":["go","http","weather","bom","api-error"],"backgroundTag":"http-non-200-response","analyzedSha":"bb838c1ccb0f0f3223690df44afdec663d622881","analyzedAt":"2026-09-03T17:02:45.030Z","contentChangedAt":"2026-09-03T17:02:45.030Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}