ramensoftware/windhawk · error · PortableSettingsException
throw PortableSettingsException(error)
Error message
throw PortableSettingsException(error)
What it means
portable_settings.cpp defines PortableSettingsException as the throw mechanism for Win32 errors encountered by the portable-settings component. When WIL's THROW_WIN32 is unavailable, PORTABLE_SETTINGS_THROW_WIN32(error) throws PortableSettingsException(error) wrapping the Win32 error code, so callers get an exception carrying the exact GetLastError value from settings file/directory operations.
Solutions
- Check the wrapped Win32 error code in the exception to identify the exact OS failure.
- Ensure the portable settings directory exists and is writable by the running user (fix ACLs or move the portable path off read-only media).
- Close other processes locking the settings file, or retry after the lock is released.
- Verify the portable flag/path configuration points at a valid location before launch.
Example fix
// before (C++ caller, no handling)
PortableLoadSettings(path);
// after
try { PortableLoadSettings(path); }
catch (const PortableSettingsException& e) {
LOG("portable settings failed: %u", e.GetError());
// fall back to defaults or a writable path
} Defensive patterns
Strategy: try-catch
Try / catch
try
{
PortableLoadSettings();
}
catch (const PortableSettingsException& e)
{
switch (e.GetError())
{
case ERROR_ACCESS_DENIED: /* fix ACLs / run elevated */ break;
case ERROR_FILE_NOT_FOUND: /* fall back to defaults */ break;
default: LOG("portable settings error %u", e.GetError()); break;
}
} Prevention
- Verify the portable settings directory exists and is writable before launch.
- Don't place the portable path on read-only or removable media.
- Avoid concurrent processes writing the same settings file.
- Check free disk space before settings writes.
When it happens
Trigger: A Win32 call inside portable settings (creating/opening the settings file or directory, reading/writing configuration) fails and the failure path expands to throw PortableSettingsException(GetLastError-derived error).
Common situations: Settings directory not writable (access denied), portable-mode path on a read-only or missing drive, file locked by another process, or disk full while persisting settings.
Related errors
- throw ResultException(failure)
- GetPrivateProfileString
- RegDeleteValue
- RegEnumValue
- Failed to start the global hooking session
AI-assisted analysis of ramensoftware/windhawk@61d99ed8e1 (2026-09-12).
Data as JSON: /api/errors/59c84d84b6de9a7e.
Report an issue: GitHub.
Appendix: source
Thrown at src/windhawk/shared/portable_settings.cpp:10
#include "stdafx.h"
#include "portable_settings.h"
// Use WIL to throw exceptions if possible.
#ifdef THROW_WIN32
#define PORTABLE_SETTINGS_THROW_WIN32(error) THROW_WIN32(error)
#else
#define PORTABLE_SETTINGS_THROW_WIN32(error) \
throw PortableSettingsException(error)
#endif
////////////////////////////////////////////////////////////////////////////////
// EnumIteratorImpl
template <typename Type>
class EnumIteratorImpl {
public:
bool is_done() const { return done; }
const std::pair<std::wstring, Type>& get_item() const { return item; }
virtual void next() = 0;
virtual std::unique_ptr<EnumIteratorImpl> clone() const = 0;
virtual ~EnumIteratorImpl() = default;
protected:
EnumIteratorImpl() = default;View on GitHub (pinned to 61d99ed8e1)