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

  1. Check the wrapped Win32 error code in the exception to identify the exact OS failure.
  2. Ensure the portable settings directory exists and is writable by the running user (fix ACLs or move the portable path off read-only media).
  3. Close other processes locking the settings file, or retry after the lock is released.
  4. 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

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


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)