Add session timeout, refactor session manager, reduce code duplication, update icons & styling
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
// Enhanced Error Handling System for CryptoVault Extension
|
||||
|
||||
class CryptoVaultError extends Error {
|
||||
constructor(message, code, retryable = false, userMessage = null) {
|
||||
super(message);
|
||||
@@ -11,35 +9,24 @@ class CryptoVaultError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
// Error codes for different types of errors
|
||||
const ERROR_CODES = {
|
||||
// Network/Connection errors (retryable)
|
||||
NETWORK_ERROR: 'NETWORK_ERROR',
|
||||
TIMEOUT_ERROR: 'TIMEOUT_ERROR',
|
||||
SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE',
|
||||
|
||||
// Authentication errors (not retryable)
|
||||
INVALID_PASSWORD: 'INVALID_PASSWORD',
|
||||
SESSION_EXPIRED: 'SESSION_EXPIRED',
|
||||
UNAUTHORIZED: 'UNAUTHORIZED',
|
||||
|
||||
// Crypto errors (not retryable)
|
||||
CRYPTO_ERROR: 'CRYPTO_ERROR',
|
||||
INVALID_SIGNATURE: 'INVALID_SIGNATURE',
|
||||
ENCRYPTION_FAILED: 'ENCRYPTION_FAILED',
|
||||
|
||||
// Validation errors (not retryable)
|
||||
INVALID_INPUT: 'INVALID_INPUT',
|
||||
MISSING_KEYPAIR: 'MISSING_KEYPAIR',
|
||||
INVALID_FORMAT: 'INVALID_FORMAT',
|
||||
|
||||
// System errors (sometimes retryable)
|
||||
WASM_ERROR: 'WASM_ERROR',
|
||||
STORAGE_ERROR: 'STORAGE_ERROR',
|
||||
UNKNOWN_ERROR: 'UNKNOWN_ERROR'
|
||||
};
|
||||
|
||||
// User-friendly error messages
|
||||
const ERROR_MESSAGES = {
|
||||
[ERROR_CODES.NETWORK_ERROR]: 'Connection failed. Please check your internet connection and try again.',
|
||||
[ERROR_CODES.TIMEOUT_ERROR]: 'Operation timed out. Please try again.',
|
||||
@@ -62,7 +49,6 @@ const ERROR_MESSAGES = {
|
||||
[ERROR_CODES.UNKNOWN_ERROR]: 'An unexpected error occurred. Please try again.'
|
||||
};
|
||||
|
||||
// Determine if an error is retryable
|
||||
const RETRYABLE_ERRORS = new Set([
|
||||
ERROR_CODES.NETWORK_ERROR,
|
||||
ERROR_CODES.TIMEOUT_ERROR,
|
||||
@@ -71,11 +57,9 @@ const RETRYABLE_ERRORS = new Set([
|
||||
ERROR_CODES.STORAGE_ERROR
|
||||
]);
|
||||
|
||||
// Enhanced error classification
|
||||
function classifyError(error) {
|
||||
const errorMessage = getErrorMessage(error);
|
||||
|
||||
// Network/Connection errors
|
||||
if (errorMessage.includes('fetch') || errorMessage.includes('network') || errorMessage.includes('connection')) {
|
||||
return new CryptoVaultError(
|
||||
errorMessage,
|
||||
@@ -85,7 +69,6 @@ function classifyError(error) {
|
||||
);
|
||||
}
|
||||
|
||||
// Authentication errors
|
||||
if (errorMessage.includes('password') || errorMessage.includes('Invalid password')) {
|
||||
return new CryptoVaultError(
|
||||
errorMessage,
|
||||
@@ -104,7 +87,6 @@ function classifyError(error) {
|
||||
);
|
||||
}
|
||||
|
||||
// Crypto errors
|
||||
if (errorMessage.includes('decryption error') || errorMessage.includes('aead::Error')) {
|
||||
return new CryptoVaultError(
|
||||
errorMessage,
|
||||
@@ -123,7 +105,6 @@ function classifyError(error) {
|
||||
);
|
||||
}
|
||||
|
||||
// Validation errors
|
||||
if (errorMessage.includes('No keypair selected')) {
|
||||
return new CryptoVaultError(
|
||||
errorMessage,
|
||||
@@ -133,7 +114,6 @@ function classifyError(error) {
|
||||
);
|
||||
}
|
||||
|
||||
// WASM errors
|
||||
if (errorMessage.includes('wasm') || errorMessage.includes('WASM')) {
|
||||
return new CryptoVaultError(
|
||||
errorMessage,
|
||||
@@ -143,7 +123,6 @@ function classifyError(error) {
|
||||
);
|
||||
}
|
||||
|
||||
// Default to unknown error
|
||||
return new CryptoVaultError(
|
||||
errorMessage,
|
||||
ERROR_CODES.UNKNOWN_ERROR,
|
||||
@@ -152,7 +131,6 @@ function classifyError(error) {
|
||||
);
|
||||
}
|
||||
|
||||
// Get error message from various error types
|
||||
function getErrorMessage(error) {
|
||||
if (!error) return 'Unknown error';
|
||||
|
||||
@@ -179,14 +157,13 @@ function getErrorMessage(error) {
|
||||
return stringified;
|
||||
}
|
||||
} catch (e) {
|
||||
// Ignore JSON stringify errors
|
||||
// Silently handle JSON stringify errors
|
||||
}
|
||||
}
|
||||
|
||||
return 'Unknown error';
|
||||
}
|
||||
|
||||
// Retry logic with exponential backoff
|
||||
async function withRetry(operation, options = {}) {
|
||||
const {
|
||||
maxRetries = 3,
|
||||
@@ -205,20 +182,16 @@ async function withRetry(operation, options = {}) {
|
||||
const classifiedError = classifyError(error);
|
||||
lastError = classifiedError;
|
||||
|
||||
// Don't retry if it's the last attempt or error is not retryable
|
||||
if (attempt === maxRetries || !classifiedError.retryable) {
|
||||
throw classifiedError;
|
||||
}
|
||||
|
||||
// Calculate delay with exponential backoff
|
||||
const delay = Math.min(baseDelay * Math.pow(backoffFactor, attempt), maxDelay);
|
||||
|
||||
// Call retry callback if provided
|
||||
if (onRetry) {
|
||||
onRetry(attempt + 1, delay, classifiedError);
|
||||
}
|
||||
|
||||
// Wait before retrying
|
||||
await new Promise(resolve => setTimeout(resolve, delay));
|
||||
}
|
||||
}
|
||||
@@ -226,7 +199,6 @@ async function withRetry(operation, options = {}) {
|
||||
throw lastError;
|
||||
}
|
||||
|
||||
// Enhanced operation wrapper with loading states
|
||||
async function executeOperation(operation, options = {}) {
|
||||
const {
|
||||
loadingElement = null,
|
||||
@@ -235,7 +207,6 @@ async function executeOperation(operation, options = {}) {
|
||||
onProgress = null
|
||||
} = options;
|
||||
|
||||
// Show loading state
|
||||
if (loadingElement) {
|
||||
setButtonLoading(loadingElement, true);
|
||||
}
|
||||
@@ -253,25 +224,21 @@ async function executeOperation(operation, options = {}) {
|
||||
}
|
||||
});
|
||||
|
||||
// Show success message if provided
|
||||
if (successMessage) {
|
||||
showToast(successMessage, 'success');
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
// Show user-friendly error message
|
||||
showToast(error.userMessage || error.message, 'error');
|
||||
throw error;
|
||||
} finally {
|
||||
// Hide loading state
|
||||
if (loadingElement) {
|
||||
setButtonLoading(loadingElement, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Export for use in other modules
|
||||
window.CryptoVaultError = CryptoVaultError;
|
||||
window.ERROR_CODES = ERROR_CODES;
|
||||
window.classifyError = classifyError;
|
||||
|
Reference in New Issue
Block a user