In 2.0 the SDK reports failures as values, not rejected promises. show() never rejects, and the bridge methods resolve with { success: false } rather than throwing, so a missing catch can no longer wedge an integration.
EncoreErrorInfo
A native failure, flattened for the bridge.
type is the stable identifier string. The two native EncoreError hierarchies differ in shape, so the bridge sends the identifier rather than reconstructing a JavaScript class from it.
Where errors arrive
Presentation failures
A failure that stopped the sheet appearing lands on the PresentationResult as not_presented with reason.type === 'error':
Do not gate your fallback on the error branch. not_presented also covers no_offer_available, experiment_control, and use_case_unavailable, none of which are failures, and all of which still need your original flow to continue.
Claim failures
A claim that errored after the sheet appeared surfaces on the advertiser axis instead, as advertiser: { type: 'failed', error }. The user never saw it.
Purchase failures
Throwing from your purchase controller records publisher: 'failed' with your error message, and the flow continues. Return 'cancelled' for a user cancellation and 'pending' for a deferred purchase rather than throwing either.
Bridge-level failures
Every bridge method is wrapped: a native call that fails logs a [Encore] warning and resolves with a fallback rather than rejecting, so a bridge fault can never crash the host app.
For show(), that fallback is a not_presented result carrying error.type === 'bridge_error'.