{"record":{"id":"0807c6d0a7aa4373","repo":"apache/seatunnel","slug":"get-myhours-token-faile","errorCode":"GET_MYHOURS_TOKEN_FAILE","errorMessage":"Login http client execute exception, http response status code:[%d], content:[%s]","messagePattern":"Login http client execute exception, http response status code:\\[(.+?)\\], content:\\[(.+?)\\]","errorType":"error_code","errorClass":"MyHoursConnectorException","httpStatus":null,"severity":"error","filePath":"seatunnel-connectors-v2/connector-http/connector-http-myhours/src/main/java/org/apache/seatunnel/connectors/seatunnel/myhours/source/MyHoursSource.java","lineNumber":89,"sourceCode":"        HttpClientProvider loginHttpClient = new HttpClientProvider(myHoursLoginParameter);\n        try {\n\n            HttpResponse response =\n                    loginHttpClient.execute(\n                            this.httpParameter.getUrl(),\n                            this.httpParameter.getMethod().getMethod(),\n                            this.httpParameter.getHeaders(),\n                            this.httpParameter.getParams(),\n                            this.httpParameter.getBody(),\n                            this.httpParameter.isKeepParamsAsForm());\n            if (HttpResponse.STATUS_OK == response.getCode()) {\n                String content = response.getContent();\n                if (!Strings.isNullOrEmpty(content)) {\n                    Map<String, String> contentMap = JsonUtils.toMap(content);\n                    return contentMap.get(MyHoursSourceOptions.ACCESS_TOKEN);\n                }\n            }\n            throw new MyHoursConnectorException(\n                    MyHoursConnectorErrorCode.GET_MYHOURS_TOKEN_FAILE,\n                    String.format(\n                            \"Login http client execute exception, http response status code:[%d], content:[%s]\",\n                            response.getCode(), response.getContent()));\n        } catch (Exception e) {\n            throw new MyHoursConnectorException(\n                    MyHoursConnectorErrorCode.GET_MYHOURS_TOKEN_FAILE,\n                    \"Login http client execute exception\");\n        } finally {\n            try {\n                loginHttpClient.close();\n            } catch (IOException e) {\n                log.warn(e.getMessage(), e);\n            }\n        }\n    }\n}\n","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-http/connector-http-myhours/src/main/java/org/apache/seatunnel/connectors/seatunnel/myhours/source/MyHoursSource.java#L71-L107","documentation":"MyHoursSource.getAccessToken() performs an HTTP login request to the MyHours API and expects an access_token in the JSON response. When the response status code is not successful (or the token field is missing), the connector throws MyHoursConnectorException with code GET_MYHOURS_TOKEN_FAILE including the HTTP status code and response body for diagnosis.","triggerScenarios":"POST to the MyHours login endpoint returns a non-2xx status (wrong email/password, locked account, API outage), or returns 2xx with a body lacking the ACCESS_TOKEN field; the exception is built from response.getCode() and response.getContent().","commonSituations":"Incorrect or expired MyHours credentials in config (api_email/api_password), MyHours API endpoint/base-url misconfiguration, account rate limiting, or the API returning an error JSON instead of a token.","solutions":["Verify the MyHours email and password options in the source config are correct and the account is active.","Inspect the response content in the error message to identify the API-reported reason (invalid credentials, 429, 5xx).","Confirm the MyHours API base URL/endpoint matches the current MyHours API version.","Retry after resolving account lockout or transient API outages."],"exampleFix":"// before\nsource {\n  MyHours {\n    url = \"https://api.myhours.com\"\n    email = \"wrong@example.com\"\n    password = \"old-password\"\n  }\n}\n\n// after\nsource {\n  MyHours {\n    url = \"https://api.myhours.com\"\n    email = \"user@example.com\"\n    password = \"current-password\"\n  }\n}","handlingStrategy":"validation","validationCode":"// Pre-check credentials outside the pipeline:\ncurl -s -o /dev/null -w \"%{http_code}\" -X POST https://api.myhours.com/api/v1/tokens -H 'Content-Type: application/json' -d '{\"email\":\"...\",\"password\":\"...\"}'\n// Expect 200; non-2xx means the connector will throw GET_MYHOURS_TOKEN_FAILE.","typeGuard":null,"tryCatchPattern":"try {\n    runSeaTunnelJob(config);\n} catch (MyHoursConnectorException e) {\n    if (MyHoursConnectorErrorCode.GET_MYHOURS_TOKEN_FAILE.equals(e.getErrorCode())) {\n        log.error(\"MyHours login failed, check credentials: {}\", e.getMessage());\n    }\n    throw e;\n}","preventionTips":["Rotate and verify MyHours credentials before deployments.","Test the login endpoint with curl whenever the connector fails at startup.","Never hardcode expired passwords; source them from a secret manager."],"tags":["seatunnel","http","authentication","myhours"],"backgroundTag":"authentication-required","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}