{"record":{"id":"240cde4b477fc479","repo":"MyCATApache/Mycat-Server","slug":"failed-to-parse-time-string-str","errorCode":null,"errorMessage":"Failed to parse time string: ${str}","messagePattern":"Failed to parse time string: (.+?)","errorType":"validation","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"src/main/java/io/mycat/memory/unsafe/utils/JavaUtils.java","lineNumber":151,"sourceCode":"      .put(\"g\", ByteUnit.GiB)\n      .put(\"gb\", ByteUnit.GiB)\n      .put(\"t\", ByteUnit.TiB)\n      .put(\"tb\", ByteUnit.TiB)\n      .put(\"p\", ByteUnit.PiB)\n      .put(\"pb\", ByteUnit.PiB)\n      .build();\n\n  /**\n   * Convert a passed time string (e.g. 50s, 100ms, or 250us) to a time count in the given unit.\n   * The unit is also considered the default if the given string does not specify a unit.\n   */\n  public static long timeStringAs(String str, TimeUnit unit) {\n    String lower = str.toLowerCase().trim();\n\n    try {\n      Matcher m = Pattern.compile(\"(-?[0-9]+)([a-z]+)?\").matcher(lower);\n      if (!m.matches()) {\n        throw new NumberFormatException(\"Failed to parse time string: \" + str);\n      }\n\n      long val = Long.parseLong(m.group(1));\n      String suffix = m.group(2);\n\n      // Check for invalid suffixes\n      if (suffix != null && !timeSuffixes.containsKey(suffix)) {\n        throw new NumberFormatException(\"Invalid suffix: \\\"\" + suffix + \"\\\"\");\n      }\n\n      // If suffix is valid use that, otherwise none was provided and use the default passed\n      return unit.convert(val, suffix != null ? timeSuffixes.get(suffix) : unit);\n    } catch (NumberFormatException e) {\n      String timeError = \"Time must be specified as seconds (s), \" +\n              \"milliseconds (ms), microseconds (us), minutes (m or min), hour (h), or day (d). \" +\n              \"E.g. 50s, 100ms, or 250us.\";\n\n      throw new NumberFormatException(timeError + \"\\n\" + e.getMessage());","sourceCodeStart":133,"sourceCodeEnd":169,"githubUrl":"https://github.com/MyCATApache/Mycat-Server/blob/65f8d8beb752f935752f2a0eec0ab017facab9ef/src/main/java/io/mycat/memory/unsafe/utils/JavaUtils.java#L133-L169","documentation":"JavaUtils.timeStringAs parses duration strings like \"50s\", \"100ms\". It throws NumberFormatException when the trimmed lowercase input does not match the pattern (-?[0-9]+)([a-z]+)?, meaning the string is empty, non-numeric, or otherwise malformed.","triggerScenarios":"Passing a config value such as \"\", \"50 s\", \"1.5s\", \"abc\", or a value containing uppercase after trim fails to match (note lowercase() handles case) to timeStringAs/timeStringAsMs/timeStringAsSec.","commonSituations":"YAML/properties config with a quoted empty string, fractional durations like \"1.5h\", values with spaces or underscores, or environment-variable placeholders left unresolved.","solutions":["Correct the config value to match the accepted format: a signed integer with optional unit suffix (e.g. 50s, 100ms, 250us).","Convert fractional values to the smallest unit first (1.5h → 90m).","Trim/strip whitespace inside the string if it contains internal spaces.","Provide a valid default when the config entry may be absent or empty."],"exampleFix":"// before\nlong ms = JavaUtils.timeStringAsMs(conf.get(\"timeout\")); // \"1.5s\"\n// after\nlong ms = JavaUtils.timeStringAsMs(\"1500ms\");","handlingStrategy":"validation","validationCode":"static boolean isValidTimeString(String s) {\n  return s != null && s.trim().toLowerCase().matches(\"-?[0-9]+([a-z]+)?\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  long ms = JavaUtils.timeStringAsMs(raw);\n} catch (NumberFormatException e) {\n  ms = defaultMillis; // log e.getMessage() for the nested cause\n}","preventionTips":["Use integer values with unit suffixes: 50s, 100ms, 250us — no spaces or fractions.","Convert fractional durations (1.5h) to a whole smaller unit (90m) yourself.","Provide defaults when config entries are optional or possibly empty."],"tags":["java","parsing","configuration","duration"],"backgroundTag":"invalid-duration-format","analyzedSha":"65f8d8beb752f935752f2a0eec0ab017facab9ef","analyzedAt":"2026-09-11T00:12:21.696Z","contentChangedAt":"2026-09-11T00:12:21.696Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}