Error Handling and Strict Mode - danielep71/VBA-Performance_Manager GitHub Wiki

Error Handling and Strict Mode

This page explains how cPerformanceManager handles invalid usage, when it raises errors, and how the StrictMode property changes behavior.

This is one of the most important pages in the documentation because the class is designed not only to measure time, but also to protect the caller from incorrect timing usage.

Why this page matters

A timing utility can fail in two very different ways:

  1. it can fail because the environment does not support the requested backend
  2. it can fail because the caller used the timing session incorrectly

cPerformanceManager explicitly addresses both cases.

It does this through:

  • session validation
  • method validation
  • backend availability checks
  • the StrictMode property
  • checkpoint/reporting contract validation

What StrictMode is

StrictMode controls whether the class should fail fast on invalid usage, or instead attempt to coerce/fallback where that is explicitly supported.

Default value:

True

What strict mode affects

In the current class design, strict mode directly affects these areas:

  • Method_NormalizeStart
  • Method_ResolveElapsed
  • Get_SystemTimeMs

It therefore influences:

  • StartTimer
  • ElapsedSeconds
  • ElapsedTime
  • any helper paths that depend on those routines

In strict mode

The class raises when:

  • the requested method is invalid
  • QPC is requested but unavailable
  • elapsed time is requested before a session exists
  • an explicit elapsed-time method does not match the active session method
  • method resolution ends in an impossible state
  • timeGetSystemTime fails when method 4 is used through the helper path

In non-strict mode

The class tries to recover where recovery has been explicitly defined.

Examples:

  • invalid StartTimer method values default to method 5
  • method 5 falls back to method 2 if QPC is unavailable
  • invalid explicit elapsed-time methods fall back to the active method
  • explicit elapsed-time method mismatches fall back to the active method
  • Get_SystemTimeMs returns 0 instead of raising when the API call fails

Checkpoint/reporting errors

These are part of the broader error model but are not controlled by StrictMode.

The class raises when:

  • Checkpoint is called before StartTimer
  • SetRunLabel is called after the first checkpoint in the current timing session

Error numbers currently used by the class

Based on the current implementation, these are the explicit class-level error numbers.

Offset Source Meaning
+1000 Method_NormalizeStart Invalid timer method passed to StartTimer
+1001 Method_NormalizeStart QPC requested but unavailable
+1002 Method_ResolveElapsed ElapsedSeconds called before StartTimer
+1003 Method_ResolveElapsed Invalid explicit method passed to ElapsedSeconds
+1004 Method_ResolveElapsed Explicit elapsed method does not match active session method
+1005 ElapsedSeconds Defensive fallback: resolved method is invalid
+1006 Get_SystemTimeMs timeGetSystemTime failed
+1010 Checkpoint Checkpoint called before StartTimer
+1011 SetRunLabel RunLabel set after checkpoint capture has begun

Recommended way to think about these errors

The custom errors fall into three categories.

Category 1: caller misuse

These are the most common:

  • invalid start method
  • invalid elapsed method
  • elapsed read before session start
  • method mismatch inside a session
  • checkpoint before session start
  • late run-label assignment

These usually indicate a bug in calling code.

Category 2: environment/backend availability

For example:

  • QPC unavailable

This indicates that the requested timing backend cannot be used as requested.

Category 3: defensive/internal safeguard

For example:

  • “resolved method is invalid”

This should normally never happen unless there is an unexpected internal state or logic break.

Recommended policy for most users

During development and validation:

cPM.StrictMode = True

Use non-strict mode only if you deliberately want the documented fallback behavior and you understand what that means for correctness.

Best-practice summary

  • prefer strict mode when correctness matters
  • always clean up in a CleanExit path
  • use MethodName() and ActiveMethodID in debugging output
  • do not mix methods inside one timing session
  • set RunLabel before the first checkpoint
  • treat custom class errors as useful signals rather than noise