What does HRESULT 0x80020009 (DISP_E_EXCEPTION) mean?

 
Previous Next
DISP_E_BADVARTYPE DISP_E_OVERFLOW

DISP_E_EXCEPTION

Automation target raised an exception

DISP_E_EXCEPTION is HRESULT 2147614729 (0x80020009) from winerror.h. AllStat describes it as “Exception occurred.” The value must be interpreted at IDispatch::Invoke returning component-provided failure details through EXCEPINFO, because the same high-level symptom can come from a different contract boundary and require different cleanup.

The decisive interpretation for DISP_E_EXCEPTION is that the invoked method or property executed far enough to raise an application exception rather than an argument-binding error. Treat DISP_E_EXCEPTION as a contract result from its owning subsystem and retain the unmodified HRESULT in logs and test assertions.

Where the result appears

  • DISP_E_EXCEPTION is returned while Automation binds or executes IDispatch::Invoke returning component-provided failure details through EXCEPINFO.
  • For DISP_E_EXCEPTION, retain the member name and DISPID, invocation flags, LCID, cArgs, cNamedArgs, and the exact VARIANTARG sequence in reverse Automation order.
  • The output contract for DISP_E_EXCEPTION includes puArgErr, EXCEPINFO, result VARIANT, by-reference values, and SAFEARRAY lock or ownership state; inspect them before cleanup.

Map DISP_E_EXCEPTION to one concrete invocation and one concrete object or metadata identity before interpreting the human-readable description.

Typical causes and interpretation boundary

Common cause categories for DISP_E_EXCEPTION are: application validation fails; a script exception escapes; a server translates its internal error into EXCEPINFO; property code throws. For DISP_E_EXCEPTION, the evidence should distinguish configuration, lifetime, input, identity, resource, and version failures rather than grouping them.

The check that separates DISP_E_EXCEPTION from nearby HRESULTs is: the invoked method or property executed far enough to raise an application exception rather than an argument-binding error. The text of DISP_E_EXCEPTION narrows the search, but the owning API state must confirm the condition before automation changes the system.

Evidence and telemetry

  • Record DISP_E_EXCEPTION with the object CLSID or ProgID, interface identity, member DISPID, dispatch flags, and type-library version.
  • For DISP_E_EXCEPTION, capture EXCEPINFO source, description, help context and scode; member DISPID; inputs; component logs; deferred-fill callback result.
  • Log VARIANT type tags, dimensions, bounds, lengths, and null/empty distinctions for DISP_E_EXCEPTION, but redact actual confidential argument values.
  • Preserve the caller language/runtime, generated interop version, LCID, and whether the call crossed a process boundary when DISP_E_EXCEPTION occurs.
  • After DISP_E_EXCEPTION, call VariantClear, SysFreeString, SafeArrayDestroy, or release interfaces only for values whose ownership was transferred by the documented contract.

For privacy-safe diagnosis of DISP_E_EXCEPTION, capture the call schema and state transitions but hash or omit confidential payloads.

Diagnostic sequence

  • Capture DISP_E_EXCEPTION (0x80020009) at IDispatch::GetIDsOfNames or IDispatch::Invoke before the language runtime converts it to a script exception.
  • For <code>DISP_E_EXCEPTION</code>, resolve the deployed member signature from ITypeInfo and compare its DISPIDs, parameter flags, VARTYPEs, optional values, and property-put rules with the caller.
  • Prove the decisive condition for DISP_E_EXCEPTION: the invoked method or property executed far enough to raise an application exception rather than an argument-binding error.
  • Inspect the likely binding or representation causes for DISP_E_EXCEPTION: application validation fails; a script exception escapes; a server translates its internal error into EXCEPINFO; property code throws.
  • Reconstruct DISPPARAMS exactly, including reverse positional ordering and named argument placement, then reproduce DISP_E_EXCEPTION with the smallest value set.
  • Verify the result VARIANT, EXCEPINFO, puArgErr, by-reference arguments, SAFEARRAY lock count, and object state after DISP_E_EXCEPTION before deciding on retry.

Correct handling and recovery

For DISP_E_EXCEPTION, the appropriate recovery is to preserve EXCEPINFO before freeing BSTRs, report the component-specific message safely, and correct the underlying application condition rather than changing dispatch syntax. Recovery from DISP_E_EXCEPTION should name the component responsible for retry and the evidence that makes another attempt safe.

The failure path for DISP_E_EXCEPTION should leave outputs in a known state and avoid double release, double commit, or reuse of stale pointers.

Practical scenario

A report server throws a domain exception for a closed accounting period; the client displays the sanitized EXCEPINFO description and does not retry.

To prevent recurrence of DISP_E_EXCEPTION, preserve a minimal fixture that asserts both the failing condition and the state after recovery.

Difference from related HRESULTs

DISP_E_BADCALLEE indicates a broken callee contract; DISP_E_EXCEPTION is the normal Automation container for an application-level exception.

Classify DISP_E_EXCEPTION by the stated contract difference, since severity bits alone do not determine the correct response.

Developer and administrator guidance

Automation adapters should handle DISP_E_EXCEPTION at the dispatch boundary and expose the member, parameter, and type information needed to repair the call. A generic retry after <code>DISP_E_EXCEPTION</code> with unchanged DISPPARAMS usually repeats the same deterministic binding error.

For DISP_E_EXCEPTION, deployment owners should compare the registered type library and server binary as one versioned unit. After <code>DISP_E_EXCEPTION</code>, re-registering arbitrary DLLs or changing locale system-wide is inappropriate unless the captured metadata proves registration or LCID drift.

References


Looking for a different code? Search another status or error code.