Skip to main content

onError

Optional callback prop on <BTProvider>. Fires whenever the underlying BLE stack or the SDK's characteristic parser encounters a failure that should be surfaced to your app.

Signature​

import type { BluetoothError, BluetoothErrorCode, DeviceData } from "@ovok/native";

export interface ErrorCallback {
deviceData?: DeviceData;
error: BluetoothError | Error | string;
code?: BluetoothErrorCode;
}

onError?: (data: ErrorCallback) => void;

deviceData is undefined for errors raised before a device is identified. Once a known device is matched, subsequent errors normally carry the related DeviceData. Use code when present; do not parse a translated message as a machine-readable identifier.

When it fires​

TriggerdeviceDataerror shape
BLE adapter powered offundefined or known devicenormalized Bluetooth error
Permission revoked mid-scanundefinedbluetooth.permission-denied when classified
Scan throttling by OSundefinedbluetooth.scan-failed when classified
Device disconnected during a measurementthe device when knownconnection error
Parser rejected a framethe device when knownframe/measurement error
Pairing failurethe device when knownbluetooth.pairing-required when classified

The union of BleError | Error | string means you cannot assume .message exists. Always narrow:

function asMessage(e: BleError | Error | string): string {
return typeof e === "string" ? e : e.message;
}

Usage​

import React, { useCallback } from "react";
import { Alert } from "react-native";
import { BTProvider } from "@ovok/native";

function MyApp() {
const handleError = useCallback((data) => {
const message = typeof data.error === "string" ? data.error : data.error.message;

if (message.toLowerCase().includes("permission")) {
Alert.alert(
"Bluetooth Permission Needed",
"Please grant Bluetooth and Location permissions in Settings.",
);
return;
}

if (message.toLowerCase().includes("disconnect")) {
// Transient — let the user retry. The SDK will re-scan automatically.
console.warn(
`Device ${data.deviceData?.name ?? "unknown"} disconnected:`,
message,
);
return;
}

// Anything else — surface it.
Alert.alert("Bluetooth Error", message);
}, []);

return (
<BTProvider /* ...other props */ onError={handleError}>
<YourScreens />
</BTProvider>
);
}

Don't confuse with DeviceStatus.Error​

There is no DeviceStatus.Error value — the DeviceStatus enum has only 4 values. "Error" is purely a UI label your app derives from onError firing. If you want the rest of your code to treat errors as a status, mirror them into your own state machine:

const [uiStatus, setUiStatus] = useState<UILabel>("idle");

const handleError = useCallback((data) => {
setUiStatus("error");
}, []);

const handleDeviceStatusChanged = useCallback((data) => {
// Map the 4 SDK values to your richer UI labels here.
}, []);

Recovery​

Connection setup retries a bounded number of times internally. After onError fires:

  • Permission failures → drive permissionFallback UI via onAccessPermissionChanged.
  • Transient disconnects → the provider keeps scanning; the manager de-duplicates a peripheral while it is already known and will surface it again after the device is removed by the connection lifecycle.
  • Parser failures → safe to ignore one frame; if they repeat, the device firmware may have a different revision than the SDK expects (file an issue with the device model + firmware version).