feat: Enhance authentication middleware and token refresh logic with improved caching, retry mechanisms, and error handling

This commit is contained in:
2025-07-10 13:31:58 -04:00
parent 6e99f4f783
commit 2928d9a7ed
3 changed files with 138 additions and 22 deletions

View File

@@ -655,9 +655,6 @@ async function addReceiptImages(doc: PDFKit.PDFDocument, expenses: Expense[]) {
async function fetchReceiptImage(receipt: any): Promise<Buffer | null> {
try {
const client = getMinioClient();
const bucketName = useRuntimeConfig().minio.bucketName;
// Determine the file path - try multiple possible sources
let rawPath = null;
@@ -683,7 +680,70 @@ async function fetchReceiptImage(receipt: any): Promise<Buffer | null> {
console.log('[expenses/generate-pdf] Raw path from receipt:', rawPath);
// Extract MinIO path from S3 URL or use as-is if it's already a path
// Check if this is an S3 URL (HTTP/HTTPS)
if (rawPath.startsWith('http://') || rawPath.startsWith('https://')) {
console.log('[expenses/generate-pdf] Detected S3 URL, fetching directly...');
try {
// Fetch image directly from S3 URL
const response = await fetch(rawPath, {
method: 'GET',
headers: {
'Accept': 'image/*'
},
// Add timeout to prevent hanging
signal: AbortSignal.timeout(30000) // 30 second timeout
});
if (!response.ok) {
console.error(`[expenses/generate-pdf] Failed to fetch image from S3: ${response.status} ${response.statusText}`);
return null;
}
// Convert response to buffer
const arrayBuffer = await response.arrayBuffer();
const imageBuffer = Buffer.from(arrayBuffer);
console.log('[expenses/generate-pdf] Successfully fetched image from S3 URL, Size:', imageBuffer.length);
return imageBuffer;
} catch (fetchError: any) {
console.error('[expenses/generate-pdf] Error fetching from S3 URL:', fetchError.message);
// If it's a timeout, try once more with a longer timeout
if (fetchError.name === 'TimeoutError' || fetchError.name === 'AbortError') {
console.log('[expenses/generate-pdf] Retrying with longer timeout...');
try {
const retryResponse = await fetch(rawPath, {
method: 'GET',
headers: {
'Accept': 'image/*'
},
signal: AbortSignal.timeout(60000) // 60 second timeout for retry
});
if (retryResponse.ok) {
const arrayBuffer = await retryResponse.arrayBuffer();
const imageBuffer = Buffer.from(arrayBuffer);
console.log('[expenses/generate-pdf] Successfully fetched image on retry, Size:', imageBuffer.length);
return imageBuffer;
}
} catch (retryError) {
console.error('[expenses/generate-pdf] Retry also failed:', retryError);
}
}
return null;
}
}
// If not an S3 URL, try MinIO as fallback
console.log('[expenses/generate-pdf] Not an S3 URL, trying MinIO fallback...');
const client = getMinioClient();
const bucketName = useRuntimeConfig().minio.bucketName;
// Extract MinIO path from the raw path
let minioPath = extractMinioPath(rawPath);
if (!minioPath) {