feat: enhanced error handing when inspecting processes. Added an intenal lookup table (map) of certain error codes that might show up on win-witr. also changed "Process Ancestry" to "Why It Exists" to match the original witr. etc#52
Conversation
…nal lookup table (map) of certain error codes that might show up on win-witr. also changed "Process Ancestry" to "Why It Exists" to match the original witr. etc
WalkthroughAdds Windows-specific runtime error hinting and parent-process detection in Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In `@main.cpp`:
- Around line 272-293: The comparisons against currentParentExe are
case-sensitive; normalize currentParentExe to a consistent case (e.g.,
lowercase) before the if/else chain so names like "POWERSHELL.EXE" match; create
a parentLower (or similar) string from currentParentExe using a case-folding
routine (std::transform with ::tolower or an equivalent) and replace uses of
currentParentExe in the subsequent checks (the if/else chain comparing
"powershell.exe", "pwsh.exe", "cmd.exe", "WindowsTerminal.exe", "explorer.exe",
"wsl.exe", "wslhost.exe", "git-bash.exe") with parentLower.
- Around line 503-525: The code logs an error when OpenProcess fails but
continues execution, leading to undefined behavior when
QueryFullProcessImageNameA and CloseHandle are later called with a NULL
hProcess; after handling/logging the failure (the block that sets queryError,
writes to std::cerr and calls PrintErrorHints), return early from the function
to avoid using hProcess, or otherwise skip the subsequent calls that use
hProcess; locate the OpenProcess failure handling around hProcess, pid,
IsVirtualTerminalModeEnabled(), PrintErrorHints(), QueryFullProcessImageNameA(),
and CloseHandle() and insert the early return (or conditional guard) immediately
after the error handling so no further APIs are invoked with a NULL handle.
- Around line 329-341: Remove the dead variable currentParentPid: delete its
declaration and the assignment inside the Process32First/Process32Next loop (the
lines declaring DWORD currentParentPid = 0; and setting currentParentPid =
pe32.th32ParentProcessID;). Keep currentProcessId and existing parentPid logic
intact so behavior is unchanged; no other changes required.
🧹 Nitpick comments (5)
main.cpp (5)
57-57:thread_localis unnecessary for a single-threaded CLI application.This tool doesn't spawn threads that would each need their own copy of
currentParentExe. Using a plainstaticor just a regular global string would be simpler and avoid TLS overhead.Suggested fix
-thread_local std::string currentParentExe = ""; // to store the name of our own parent process for error hints +std::string currentParentExe = ""; // to store the name of our own parent process for error hints
117-121: Consider adding a trailing comma for easier future additions.The entry for error code 31 lacks a trailing comma. While syntactically valid, adding one makes it easier to add new entries without modifying existing lines.
Suggested fix
std::unordered_map<int, std::string> errorHints = { {5, "Access is denied."}, {87, "The process or PID doesn't exist."}, - {31, "This error indicates a driver error, but in win-witr, it often means you are calling a pseudo-process, such as System, Registry, or other processes that only exist in RAM as a kernel process. It is often easy to tell them apart if they lack a .exe extension."} + {31, "This error indicates a driver error, but in win-witr, it often means you are calling a pseudo-process, such as System, Registry, or other processes that only exist in RAM as a kernel process. It is often easy to tell them apart if they lack a .exe extension."},
263-269: Minor: double map lookup can be avoided.Using
find()and thenoperator[]performs two lookups. Use the iterator fromfind()directly.Suggested fix
- if (errorHints.find(errorCode) != errorHints.end()) { + auto it = errorHints.find(errorCode); + if (it != errorHints.end()) { if (IsVirtualTerminalModeEnabled()) { - std::cerr << "\033[1;33mHint:\033[0m " << errorHints[errorCode] << std::endl; + std::cerr << "\033[1;33mHint:\033[0m " << it->second << std::endl; } else { - std::cerr << "Hint: " << errorHints[errorCode] << std::endl; + std::cerr << "Hint: " << it->second << std::endl; }
520-522: RedundantqueryErrorcheck - it's always true at this point.
queryErroris set totrueon lines 508/514 before the error is printed, so the check on line 520 will always be true. Either remove the check or restructure the logic if you intend to conditionally callPrintErrorHints.Simplified version
} - if (queryError) { PrintErrorHints(errorCode); - }
548-556: Same redundant check pattern as above.The comment explains the intent well (multiple error paths can occur), but within this specific block,
queryErroris always true when checked. The variable could be useful if you want to track "any error occurred" across the entire function, but currently each block independently sets and checks it.
Summary by CodeRabbit
New Features
Reliability
✏️ Tip: You can customize this high-level summary in your review settings.