{"record":{"id":"734b31dace8c8519","repo":"languagetool-org/languagetool","slug":"ioexception-during-dictionary-list-loading","errorCode":null,"errorMessage":"IOException during dictionary list loading","messagePattern":"IOException during dictionary list loading","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-language-modules/uk/src/main/java/org/languagetool/rules/uk/ExtraDictionaryLoader.java","lineNumber":68,"sourceCode":"    }\n    return result;\n  }\n\n  public static Map<String, List<String>> loadLists(String path) {\n    Map<String, List<String>> result = new HashMap<>();\n    try (InputStream is = JLanguageTool.getDataBroker().getFromRulesDirAsStream(path);\n         Scanner scanner = new Scanner(is, \"UTF-8\")) {\n      while (scanner.hasNextLine()) {\n        String line = scanner.nextLine();\n        if( ! line.startsWith(\"#\") && ! line.trim().isEmpty() ) {\n          String[] split = line.split(\" *= *|\\\\|\");\n          List<String> list = Arrays.asList(split).subList(1, split.length);\n          result.put(split[0], list);\n        }\n      }\n      return result;\n    } catch (IOException e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n}\n","sourceCodeStart":50,"sourceCodeEnd":73,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-language-modules/uk/src/main/java/org/languagetool/rules/uk/ExtraDictionaryLoader.java#L50-L73","documentation":"ExtraDictionaryLoader.loadLists() reads dictionary lists from an InputStream and wraps any IOException in an unchecked RuntimeException. This is a fail-fast pattern: the dictionary data is required for the rule to work, so the library aborts instead of silently returning partial data. The exception message is generic because the original IOException is used only as the cause.","triggerScenarios":"Calling loadLists() when the underlying data source (URL or stream) is unreachable, returns an error, or the connection drops mid-read while splitting lines into key/value lists.","commonSituations":"No network access or offline environment when loading remote dictionaries; the remote Wikipedia-derived list host is down or rate-limiting; a proxy/firewall blocks the request; TLS failures in restricted JVMs.","solutions":["Check network connectivity and make the source URL reachable (curl it from the same host).","Verify any proxy settings (-Dhttps.proxyHost/-Dhttps.proxyPort) and truststore configuration for HTTPS sources.","Inspect the cause chain (e.getCause()) to see the underlying IOException and address it specifically.","Cache the dictionary list locally and load from a local file/stream instead of the network.","If the list is no longer hosted, update the URL in the source to the new location."],"exampleFix":"// before\ntry {\n  return loadLists(stream);\n} catch (IOException e) {\n  throw new RuntimeException(e);\n}\n// after\ntry {\n  return loadLists(stream);\n} catch (IOException e) {\n  throw new RuntimeException(\"Failed to load extra dictionary lists from \" + sourceUrl, e);\n}","handlingStrategy":"try-catch","validationCode":"URL url = new URL(sourceUrl);\nHttpURLConnection c = (HttpURLConnection) url.openConnection();\nc.setConnectTimeout(5000);\nif (c.getResponseCode() != 200) throw new IllegalStateException(\"List source unreachable: \" + c.getResponseCode());","typeGuard":null,"tryCatchPattern":"try { result = loader.loadLists(stream); }\ncatch (RuntimeException e) {\n  Throwable cause = e.getCause();\n  if (cause instanceof IOException) { LOG.error(\"Dictionary list I/O failure\", cause); /* fallback to cached list */ }\n  else throw e;\n}","preventionTips":["Preflight the remote list URL (HTTP status check) before loading","Cache dictionary lists locally and fall back to the cache on I/O failure","Configure proxy/TLS settings for environments behind firewalls","Monitor cause-chain IOExceptions to detect recurring network problems"],"tags":["io","network","dictionary-loading","ukrainian"],"backgroundTag":"http-request-failed","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}