{"record":{"id":"8b394b72d780e4ff","repo":"java-native-access/jna","slug":"win32exception-error-code-from-native-getlasterror-after-8b394b","errorCode":null,"errorMessage":"Win32Exception (error code from Native.getLastError after FindNextUrlCacheEntry)","messagePattern":"Win32Exception \\(error code from Native\\.getLastError after FindNextUrlCacheEntry\\)","errorType":"error_code","errorClass":"Win32Exception","httpStatus":null,"severity":"error","filePath":"contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java","lineNumber":97,"sourceCode":"                throw new Win32Exception(Native.getLastError());\n            }\n\n            items.add(entry);\n\n            while (true) {\n                size = new IntByReference();\n\n                // for every entry, we call the API twice:\n                // once to get the size into the IntByReference\n                // then again to get the actual item\n                boolean result = Wininet.INSTANCE.FindNextUrlCacheEntry(cacheHandle, null, size);\n\n                if (!result) {\n                    lastError = Native.getLastError();\n                    if (lastError == WinError.ERROR_NO_MORE_ITEMS) {\n                        break;\n                    } else if (lastError != WinError.ERROR_SUCCESS && lastError != WinError.ERROR_INSUFFICIENT_BUFFER) {\n                        throw new Win32Exception(lastError);\n                    }\n                }\n\n                entry = new INTERNET_CACHE_ENTRY_INFO(size.getValue());\n                result = Wininet.INSTANCE.FindNextUrlCacheEntry(cacheHandle, entry, size);\n\n                if (!result) {\n                    lastError = Native.getLastError();\n                    if (lastError == WinError.ERROR_NO_MORE_ITEMS) {\n                        break;\n                    } else if (lastError != WinError.ERROR_SUCCESS && lastError != WinError.ERROR_INSUFFICIENT_BUFFER) {\n                        throw new Win32Exception(lastError);\n                    }\n                }\n                items.add(entry);\n            }\n\n            for (INTERNET_CACHE_ENTRY_INFO item : items) {","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/contrib/platform/src/com/sun/jna/platform/win32/WininetUtil.java#L79-L115","documentation":"WininetUtil.getCache() throws this Win32Exception when FindNextUrlCacheEntry fails with an error other than ERROR_NO_MORE_ITEMS, ERROR_SUCCESS, or ERROR_INSUFFICIENT_BUFFER while walking the cache. The exception carries the GetLastError() code so the developer can see the specific Win32 failure that interrupted enumeration. ERROR_NO_MORE_ITEMS is deliberately not thrown — it signals normal end of iteration.","triggerScenarios":"During the while-loop of getCache(), a call to Wininet.INSTANCE.FindNextUrlCacheEntry(cacheHandle, entry, size) returns false and GetLastError() is not one of the tolerated codes — e.g. an invalid handle because the cache handle was closed, or an internet-related hard error.","commonSituations":"Cache invalidated during a long enumeration; handle misuse across threads (WinINet handles must be used on the thread that created them); corrupted cache state.","solutions":["Ensure enumeration happens on the same thread that opened the cache handle (WinINet thread affinity)","Catch Win32Exception around getCache() and degrade gracefully (partial results or empty list)","Check the specific error code to diagnose (e.g. ERROR_INVALID_HANDLE implies thread/session misuse)","Keep enumeration short-lived or re-enumerate on failure instead of caching a long-lived FindFirstUrlCacheEntry handle"],"exampleFix":"// before\nList<INTERNET_CACHE_ENTRY_INFO> all = WininetUtil.getCache();\n// after\nList<INTERNET_CACHE_ENTRY_INFO> all;\ntry {\n    all = WininetUtil.getCache();\n} catch (Win32Exception e) {\n    all = Collections.emptyList();\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    items = WininetUtil.getCache();\n} catch (Win32Exception e) {\n    log.warn(\"cache enum failed: \" + e.getMessage());\n    items = partialOrEmpty();\n}","preventionTips":["Respect WinINet thread affinity — same thread for open and iterate","Keep enumeration sessions short","Check error code to distinguish transient vs permanent failures"],"tags":["wininet","windows","url-cache","win32-exception"],"backgroundTag":"api-error-response","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}