Skip to content

Unify native→managed error propagation; drop the managed error callback - #1969

Merged
shimat merged 2 commits into
5.xfrom
feature/error-mechanism-redesign-5x
Jun 28, 2026
Merged

shimat merged 2 commits into
5.xfrom
feature/error-mechanism-redesign-5x

Conversation

@shimat

@shimat shimat commented Jun 28, 2026

Copy link
Copy Markdown
Owner

@
Layer B of Phase 3 — closes #1966 (part of #1938). Stacked on #1968 (review/merge that first; this PRs diff is only the mechanism change).

Replaces the split error mechanism — Windows: throw a managed exception from the OpenCV error callback through native frames; *nix: record into a managed ThreadLocal via the callback — with a single portable path on all platforms.

Design

  • cvTry now wraps each body in a three-tier catch (cv::Exception → std::exception → ...) and records the caught exceptions details into a per-thread native store, captured directly from the thrown object. catch(...) guarantees any C++ exception is reported rather than crossing the P/Invoke boundary as SEHException; only non-C++ faults (SEH / SIGSEGV) pass through.
  • New exports: core_getLastException (read the per-thread record) and core_setSilentErrorHandler (install a native, managed-free no-op handler that merely mutes OpenCVs stderr dump).
  • Managed: ExceptionHandler builds OpenCVException from the native record; no CvErrorCallback delegate is installed in the default path (NativeAOT / trim friendly, removes a delegate from the Redesign legacy DisposableObject-based utilities (ArrayAddress1/2, Window, CvTrackbar, ResourcesTracker) #1941 set). HandleException simply throws on Occurred; the now-dead DOTNETCORE conditionals are removed.
  • Escape hatch: Cv2.SetErrorHandler(CvErrorCallback?) — opt-in managed handler; null restores the native silent handler.

Why its more correct

cvTry catches on the calling (P/Invoke) thread, so details are right even when cv::parallel_for_ rethrows a worker exception there. The old callback-on-worker-thread + ThreadLocal scheme recorded on the wrong thread in that case.

Notes

Requires rebuilding OpenCvSharpExtern; native build + runtime behavior verified on CI.
@

Phase 3 of the internal-layer modernization (#1966, part of #1938). Replaces
the split error mechanism (Windows: throw a managed exception from the OpenCV
error callback through native frames; *nix: record into a managed ThreadLocal
via the callback) with a single portable path on all platforms:

* cvTry now wraps every body in try/catch and records the caught exception's
  details (code/func/file/line/message) into a per-thread native store,
  captured directly from the thrown object. catch(...) ensures any C++
  exception is reported rather than crossing the boundary as SEHException;
  only non-C++ faults (SEH/SIGSEGV) pass through.
* New exports: core_getLastException (read the per-thread record) and
  core_setSilentErrorHandler (install a native, managed-free no-op handler
  that merely mutes OpenCV's stderr dump).
* Managed: ExceptionHandler builds the OpenCVException from the native record;
  no CvErrorCallback delegate is installed in the default path (NativeAOT/trim
  friendly). HandleException simply throws on Occurred; the now-dead DOTNETCORE
  conditionals are removed.
* Cv2.SetErrorHandler(CvErrorCallback?) is the opt-in escape hatch; null
  restores the native silent handler.

Because cvTry catches on the calling (P/Invoke) thread, error details are
correct even when cv::parallel_for_ rethrows a worker exception there -- the
old callback-on-worker-thread + ThreadLocal scheme was wrong in that case.

Requires rebuilding OpenCvSharpExtern; native build verified on CI.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@shimat shimat self-assigned this Jun 28, 2026
Add smoke tests for the new opt-in managed error handler:
- a custom handler is invoked on a native error while the error still surfaces
  as an OpenCVException (with the expected status/func/message);
- SetErrorHandler(null) restores the default native silent handler and errors
  still surface as OpenCVException.

The existing ExceptionTest cases already cover the default getter-based path
(native exception -> OpenCVException with code/func/file/line/message).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Base automatically changed from feature/extern-cvtry-wrapper-5x to 5.x June 28, 2026 08:39
@shimat
shimat merged commit 5b6d54f into 5.x Jun 28, 2026
14 checks passed
@shimat
shimat deleted the feature/error-mechanism-redesign-5x branch June 28, 2026 09:02
@shimat shimat added the enhancement New feature or improvement to OpenCvSharp label Jul 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or improvement to OpenCvSharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant