Documentation Index
Fetch the complete documentation index at: https://docs.go.gbgplc.com/llms.txt
Use this file to discover all available pages before exploring further.
All bridge errors are typed as BridgeError with machine-readable codes and recoverability metadata.
The BridgeError class
import { BridgeError, BridgeErrorCode } from '@gbgplc-internal/ggo-native-bridge';
try {
await bridge.request('camera.document.capture', data);
} catch (error) {
if (error instanceof BridgeError) {
console.log(error.code); // BridgeErrorCode enum value
console.log(error.message); // Human-readable description
console.log(error.recoverable); // Can the user retry?
console.log(error.correlationId); // Which request failed?
}
}
Error codes
| Code | Meaning | Recoverable | Recommended action |
|---|
UNSUPPORTED | Host doesnβt support this feature | No | Fall back to web implementation or show βnot availableβ |
PERMISSION_DENIED | User denied a required permission | Yes | Show permission explanation, offer retry |
CANCELLED | User cancelled the operation | Yes | Return to previous state, allow retry |
TIMEOUT | Host didnβt respond in time | Yes | Show timeout message, offer retry |
BUSY | Another native operation is in progress | Yes | Wait and retry, or queue the request |
INVALID_REQUEST | Request payload was malformed | No | Fix the request data (developer error) |
INTERNAL_ERROR | Unexpected host error | No | Show generic error, log for debugging |
VERSION_MISMATCH | Protocol version incompatibility | No | Update SDK or host app |
Handling patterns
There are three useful ways to react to a BridgeError: branch on the specific code, branch on the recoverable flag, or sidestep the error entirely by checking capabilities upfront. Pick whichever fits the call site β they compose naturally.
Switch on error code
async function captureDocument() {
try {
return await bridge.request('camera.document.capture', {
documentType: 'passport',
side: 'front',
}, { timeout: 120_000 });
} catch (error) {
if (!(error instanceof BridgeError)) throw error;
switch (error.code) {
case BridgeErrorCode.CANCELLED:
return null;
case BridgeErrorCode.PERMISSION_DENIED:
showPermissionDialog('Camera access is required to capture your document.');
return null;
case BridgeErrorCode.TIMEOUT:
showRetryDialog('The camera took too long to respond.');
return null;
case BridgeErrorCode.BUSY:
await delay(1000);
return captureDocument();
case BridgeErrorCode.UNSUPPORTED:
return captureWithWebCamera();
default:
showErrorDialog(`An error occurred: ${error.message}`);
return null;
}
}
}
Check recoverability
try {
await bridge.request(action, data);
} catch (error) {
if (error instanceof BridgeError) {
if (error.recoverable) {
showRetryButton(() => bridge.request(action, data));
} else {
showFallbackUI();
}
}
}
Capability check before request
Avoid errors entirely by checking capabilities first:
import { CAPABILITY_IDS } from '@gbgplc-internal/ggo-native-bridge';
async function captureWithFallback() {
const hasNativeCamera = bridge.hasCapability(CAPABILITY_IDS.CAMERA_DOCUMENT);
if (hasNativeCamera) {
try {
return await bridge.request('camera.document.capture', data);
} catch (error) {
if (error instanceof BridgeError && !error.recoverable) {
return captureWithWebCamera();
}
throw error;
}
}
return captureWithWebCamera();
}
Discovery errors
discoverCapabilities() can fail if the host doesnβt respond. The React <BridgeProvider> handles this gracefully β capabilitiesReady is still set to true, capabilities remain empty, and the app continues normally.
If using the core library directly:
try {
await bridge.discoverCapabilities(5_000);
} catch (error) {
console.warn('Capability discovery failed:', error);
}
// hasCapability() will return false for all capabilities
Request errors vs. response errors
There are two distinct error paths:
- Transport-level errors β the request never reaches the host or the response is lost (e.g.,
TIMEOUT)
- Host-level errors β the host received the request but returned an error (e.g.,
PERMISSION_DENIED, UNSUPPORTED, CANCELLED)
Both are surfaced as BridgeError instances.
Logging and debugging
// Inspect the message log after an error
const log = bridge.getMessageLog();
const recentMessages = log.slice(-10);
console.log('Recent messages:', JSON.stringify(recentMessages, null, 2));
// Set up real-time logging
bridge.onMessageLog((message, direction) => {
console.log(`[${direction}] ${message.type}: ${JSON.stringify(message.payload)}`);
});