Skip to main content

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

CodeMeaningRecoverableRecommended action
UNSUPPORTEDHost doesn’t support this featureNoFall back to web implementation or show β€œnot available”
PERMISSION_DENIEDUser denied a required permissionYesShow permission explanation, offer retry
CANCELLEDUser cancelled the operationYesReturn to previous state, allow retry
TIMEOUTHost didn’t respond in timeYesShow timeout message, offer retry
BUSYAnother native operation is in progressYesWait and retry, or queue the request
INVALID_REQUESTRequest payload was malformedNoFix the request data (developer error)
INTERNAL_ERRORUnexpected host errorNoShow generic error, log for debugging
VERSION_MISMATCHProtocol version incompatibilityNoUpdate 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:
  1. Transport-level errors β€” the request never reaches the host or the response is lost (e.g., TIMEOUT)
  2. 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)}`);
});