expo-finance-kit
Version:
Native Expo module for Apple FinanceKit - Access financial data from Apple Card and other accounts
150 lines • 5.19 kB
JavaScript
/**
* Error handling utilities for Expo Finance Kit
* Provides consistent error creation and handling
*/
import { FinanceKitErrorCode } from '../ExpoFinanceKit.types';
/**
* Creates a FinanceKit error with proper structure
* @param code - Error code
* @param message - Error message
* @param details - Additional error details
* @returns FinanceKitError
*/
export function createFinanceKitError(code, message, details) {
const error = new Error(message);
error.code = code;
error.details = details;
error.name = 'FinanceKitError';
return error;
}
/**
* Checks if an error is a FinanceKit error
* @param error - Error to check
* @returns Boolean indicating if it's a FinanceKit error
*/
export function isFinanceKitError(error) {
return (error instanceof Error &&
'code' in error &&
Object.values(FinanceKitErrorCode).includes(error.code));
}
/**
* Gets user-friendly error message
* @param error - Error to get message for
* @returns User-friendly error message
*/
export function getUserFriendlyErrorMessage(error) {
if (isFinanceKitError(error)) {
switch (error.code) {
case FinanceKitErrorCode.Unavailable:
return 'FinanceKit is not available on this device. Please ensure you are using iOS 17.4 or later.';
case FinanceKitErrorCode.Unauthorized:
return 'Access to financial data has not been authorized. Please grant permission in Settings.';
case FinanceKitErrorCode.InvalidAccountId:
return 'The specified account could not be found.';
case FinanceKitErrorCode.AccountNotFound:
return 'The requested account does not exist.';
case FinanceKitErrorCode.InvalidDateRange:
return 'The specified date range is invalid.';
case FinanceKitErrorCode.RateLimitExceeded:
return 'Too many requests. Please try again later.';
case FinanceKitErrorCode.NetworkError:
return 'Network error occurred. Please check your connection.';
default:
return error.message || 'An unexpected error occurred.';
}
}
return 'An unexpected error occurred. Please try again.';
}
/**
* Wraps an async function with error handling
* @param fn - Async function to wrap
* @returns Wrapped function with error handling
*/
export function withErrorHandling(fn) {
return (async (...args) => {
try {
return await fn(...args);
}
catch (error) {
if (isFinanceKitError(error)) {
throw error;
}
// Transform unknown errors to FinanceKit errors
throw createFinanceKitError(FinanceKitErrorCode.Unknown, error instanceof Error ? error.message : 'Unknown error occurred', { originalError: error });
}
});
}
/**
* Logs error with context
* @param error - Error to log
* @param context - Additional context
*/
export function logError(error, context) {
const timestamp = new Date().toISOString();
const errorInfo = {
timestamp,
context,
error: {
message: error.message,
code: isFinanceKitError(error) ? error.code : undefined,
details: isFinanceKitError(error) ? error.details : undefined,
stack: error.stack,
},
};
console.error('[ExpoFinanceKit Error]', errorInfo);
}
/**
* Error recovery strategies
*/
export const ErrorRecovery = {
/**
* Retries a function with exponential backoff
* @param fn - Function to retry
* @param maxRetries - Maximum number of retries
* @param initialDelay - Initial delay in milliseconds
* @returns Result of the function
*/
async retry(fn, maxRetries = 3, initialDelay = 1000) {
let lastError;
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
}
catch (error) {
lastError = error;
// Don't retry certain errors
if (isFinanceKitError(error)) {
if ([
FinanceKitErrorCode.Unauthorized,
FinanceKitErrorCode.Unavailable,
FinanceKitErrorCode.InvalidAccountId,
].includes(error.code)) {
throw error;
}
}
// Wait before retrying
if (i < maxRetries - 1) {
const delay = initialDelay * Math.pow(2, i);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
}
throw lastError;
},
/**
* Provides a fallback value if function fails
* @param fn - Function to try
* @param fallback - Fallback value
* @returns Result of function or fallback
*/
async fallback(fn, fallback) {
try {
return await fn();
}
catch (error) {
logError(error, 'Using fallback value');
return fallback;
}
},
};
//# sourceMappingURL=errors.js.map