/** * # Typed errors * * Canonical error surface for `react-native-sensitive-info`. Every failure thrown by the library * is an instance of {@link SensitiveInfoError} or one of its subclasses, classified by a stable * {@link ErrorCode} discriminant. * * Use `instanceof` (preferred) or the `is*Error` predicates to branch in catch blocks. Legacy * string-marker matching (`error.message.includes('[E_NOT_FOUND]')`) is still supported via * {@link toSensitiveInfoError} but considered legacy. * * @packageDocumentation */ /** * Stable discriminant codes emitted by the native layer. * * @remarks * | Code | Meaning | * | -------------------------- | -------------------------------------------------------------------- | * | `E_NOT_FOUND` | The requested key does not exist. | * | `E_AUTH_CANCELED` | User dismissed the biometric / device-credential prompt. | * | `E_INTEGRITY_VIOLATION` | HMAC verification failed — entry should be treated as tampered. | * | `E_KEY_INVALIDATED` | Hardware key was invalidated (e.g. biometric re-enrollment). | * | `E_ROTATION_FAILED` | `rotateKeys()` could not complete. | * | `E_UNKNOWN` | Catch-all for unclassified failures. | */ export declare const ErrorCode: { readonly NotFound: "E_NOT_FOUND"; readonly AuthenticationCanceled: "E_AUTH_CANCELED"; readonly IntegrityViolation: "E_INTEGRITY_VIOLATION"; readonly KeyInvalidated: "E_KEY_INVALIDATED"; readonly RotationFailed: "E_ROTATION_FAILED"; readonly InvalidArgument: "E_INVALID_ARGUMENT"; readonly Unknown: "E_UNKNOWN"; }; /** * Union of every value in {@link ErrorCode}. Use this to type variables that hold an error code. * * @see {@link ErrorCode} */ export type ErrorCodeValue = (typeof ErrorCode)[keyof typeof ErrorCode]; /** * Base class for every typed error thrown by the library. * * All `is*Error` predicates and the `toSensitiveInfoError` adapter funnel into subclasses of this * type, so a single `instanceof SensitiveInfoError` check is sufficient to identify any failure * originating from secure storage. * * @example * ```ts * try { * await getItem('session-token', { service: 'com.example.auth' }) * } catch (e) { * if (e instanceof SensitiveInfoError) console.log(e.code) * } * ``` */ export declare class SensitiveInfoError extends Error { /** Stable discriminant identifying the failure mode. */ readonly code: ErrorCodeValue; /** * @param code - Stable {@link ErrorCodeValue} for the failure. * @param message - Human-readable description. * @param options - Optional `cause` for error chaining (see ECMAScript 2022 `Error` cause). */ constructor(code: ErrorCodeValue, message: string, options?: { cause?: unknown; }); } /** * Type-only declaration merge that exposes the optional `cause` property on * {@link SensitiveInfoError} for consumers compiling with a `tsconfig` `lib` * target that predates ES2022 (where `Error.cause` was added). Using interface * merging—rather than a `declare` class field—keeps the source fully erasable * by Babel/SWC and avoids emitting an enumerable own property. */ export interface SensitiveInfoError { readonly cause?: unknown; } /** * The requested key does not exist in the secure store. * * Note: {@link getItem} swallows this error and returns `null` instead. You will only observe * `NotFoundError` directly when bypassing the wrapper or when implementing a custom layer atop * the native HybridObject. * * @example * ```ts * try { await native.getItem({ key: 'missing' }) } * catch (e) { if (isNotFoundError(e)) return null } * ``` */ export declare class NotFoundError extends SensitiveInfoError { /** * @param message - Defaults to `'Secret not found.'`. * @param options - Optional `cause` for error chaining. */ constructor(message?: string, options?: { cause?: unknown; }); } /** * The user dismissed the biometric / device-credential prompt. * * @remarks Treat this as a normal user gesture rather than a bug — do not retry automatically; * surface a clear UI affordance for the user to re-attempt. * * @example * ```ts * try { await getItem('token', { service: 'auth' }) } * catch (e) { if (isAuthenticationCanceledError(e)) showUnlockButton() } * ``` */ export declare class AuthenticationCanceledError extends SensitiveInfoError { /** * @param message - Defaults to `'Authentication prompt canceled by the user.'`. * @param options - Optional `cause` for error chaining. */ constructor(message?: string, options?: { cause?: unknown; }); } /** * HMAC verification of the stored metadata/ciphertext failed. This strongly suggests tampering at * rest and the affected entry should be treated as untrustworthy. * * @remarks Recommended remediation: delete the affected entry, force the user to re-authenticate * with the upstream service, and report telemetry so you can detect device-level compromise. * * @example * ```ts * try { await getItem('token', { service: 'auth' }) } * catch (e) { * if (isIntegrityViolationError(e)) { * await deleteItem('token', { service: 'auth' }) * forceReauth() * } * } * ``` */ export declare class IntegrityViolationError extends SensitiveInfoError { /** Key whose ciphertext failed verification, when known. */ readonly key?: string | undefined; /** * @param message - Defaults to `'Integrity check failed for stored secret.'`. * @param options - `cause` for error chaining and `key` for the affected identifier. */ constructor(message?: string, options?: { cause?: unknown; key?: string; }); } /** * The hardware-backed key tied to this entry was permanently invalidated (for example, because * biometrics were re-enrolled). The entry must be deleted and re-created. * * @remarks This is the expected error after a user adds/removes a fingerprint or re-enrolls Face * ID on entries written with `accessControl: 'biometryCurrentSet'` or `'secureEnclaveBiometry'`. * * @example * ```ts * try { await getItem('token', { service: 'auth' }) } * catch (e) { * if (isKeyInvalidatedError(e)) { * await deleteItem('token', { service: 'auth' }) * promptUserToSetUpAgain() * } * } * ``` */ export declare class KeyInvalidatedError extends SensitiveInfoError { /** Native keystore alias that was invalidated, when known. */ readonly alias?: string | undefined; /** * @param message - Defaults to `'The hardware key backing this entry was permanently invalidated.'`. * @param options - `cause` for error chaining and `alias` for the affected keystore entry. */ constructor(message?: string, options?: { cause?: unknown; alias?: string; }); } /** * {@link rotateKeys} could not complete for the given service. * * @example * ```ts * try { await rotateKeys({ service: 'auth' }) } * catch (e) { if (isRotationFailedError(e)) reportTelemetry(e) } * ``` */ export declare class RotationFailedError extends SensitiveInfoError { /** * @param message - Defaults to `'Key rotation failed.'`. * @param options - Optional `cause` for error chaining. */ constructor(message?: string, options?: { cause?: unknown; }); } /** * Indicates that a TS-side input violated the library's contract — for example, an empty `key`, * a service name longer than the supported limit, or a value whose serialized size exceeds the * configured ceiling. * * @remarks * This error is raised **before** any native call is made, so no biometric prompt is shown and * no on-disk state is touched. Treat it as a programmer error and fix the call site. * * @example * ```ts * try { await setItem('', value, { service: 'auth' }) } * catch (e) { if (isInvalidArgumentError(e)) console.warn(e.argument, e.message) } * ``` */ export declare class InvalidArgumentError extends SensitiveInfoError { /** Name of the argument that failed validation, when known (e.g. `'key'`, `'value'`). */ readonly argument?: string | undefined; /** * @param message - Human-readable description of the violation. * @param options - `cause` for error chaining and `argument` for the offending field name. */ constructor(message?: string, options?: { cause?: unknown; argument?: string; }); } /** * Convert a raw native/unknown error into a typed {@link SensitiveInfoError} subclass. * * @param error - Anything caught from a native call — typically an `Error` with a `code` field or * a legacy string-marker message such as `'[E_NOT_FOUND] missing key'`. * @returns The corresponding typed error subclass when classifiable, otherwise the original * error untouched (so consumers can decide how to handle unknown failures). * * @remarks Already-typed `SensitiveInfoError` instances are returned as-is. The legacy * string-marker path exists purely for back-compat with pre-typed-error releases; new code should * rely on `instanceof` against the exported subclasses. * * @example * ```ts * try { await native.setItem(req) } * catch (raw) { * const e = toSensitiveInfoError(raw) * if (e instanceof KeyInvalidatedError) await reset() * else throw e * } * ``` * * @see {@link SensitiveInfoError} */ export declare function toSensitiveInfoError(error: unknown): unknown; /** * Type guard that narrows `error` to {@link NotFoundError}. * * @param error - Anything thrown from a `react-native-sensitive-info` call. * @returns `true` when the error matches the {@link ErrorCode.NotFound} discriminant. * * @example * ```ts * try { await native.getItem({ key: 'missing' }) } * catch (e) { if (isNotFoundError(e)) return null; throw e } * ``` * * @see {@link NotFoundError} */ export declare const isNotFoundError: (error: unknown) => error is NotFoundError; /** * Type guard that narrows `error` to {@link AuthenticationCanceledError}. * * @param error - Anything thrown from a `react-native-sensitive-info` call. * @returns `true` when the user dismissed the biometric / device-credential prompt. * * @example * ```ts * try { await getItem('token', { service: 'auth' }) } * catch (e) { if (isAuthenticationCanceledError(e)) showRetry(); else throw e } * ``` * * @see {@link AuthenticationCanceledError} */ export declare const isAuthenticationCanceledError: (error: unknown) => error is AuthenticationCanceledError; /** * Type guard that narrows `error` to {@link IntegrityViolationError}. * * @param error - Anything thrown from a `react-native-sensitive-info` call. * @returns `true` when HMAC verification failed for the stored ciphertext. * * @example * ```ts * try { await getItem('token', { service: 'auth' }) } * catch (e) { * if (isIntegrityViolationError(e)) await deleteItem('token', { service: 'auth' }) * else throw e * } * ``` * * @see {@link IntegrityViolationError} */ export declare const isIntegrityViolationError: (error: unknown) => error is IntegrityViolationError; /** * Type guard that narrows `error` to {@link KeyInvalidatedError}. * * @param error - Anything thrown from a `react-native-sensitive-info` call. * @returns `true` when the hardware key backing the entry was invalidated (e.g. biometric * re-enrollment). * * @example * ```ts * try { await getItem('token', { service: 'auth' }) } * catch (e) { * if (isKeyInvalidatedError(e)) await deleteItem('token', { service: 'auth' }) * else throw e * } * ``` * * @see {@link KeyInvalidatedError} */ export declare const isKeyInvalidatedError: (error: unknown) => error is KeyInvalidatedError; /** * Type guard that narrows `error` to {@link RotationFailedError}. * * @param error - Anything thrown from a `react-native-sensitive-info` call. * @returns `true` when {@link rotateKeys} could not complete. * * @example * ```ts * try { await rotateKeys({ service: 'auth' }) } * catch (e) { if (isRotationFailedError(e)) report(e); else throw e } * ``` * * @see {@link RotationFailedError} */ export declare const isRotationFailedError: (error: unknown) => error is RotationFailedError; /** * Type guard that narrows `error` to {@link InvalidArgumentError}. * * @param error - Anything thrown from a `react-native-sensitive-info` call. * @returns `true` when a TS-side input violated the library's contract. * * @example * ```ts * try { await setItem('', value, { service: 'auth' }) } * catch (e) { if (isInvalidArgumentError(e)) showFormError(e.argument) } * ``` * * @see {@link InvalidArgumentError} */ export declare const isInvalidArgumentError: (error: unknown) => error is InvalidArgumentError; //# sourceMappingURL=errors.d.ts.map