feat: Improve UI styling in ExpenseDetailsModal and ExpenseList, enhance authentication middleware caching, and optimize PDF generation for receipt fetching
This commit is contained in:
@@ -748,56 +748,22 @@ async function fetchReceiptImage(receipt: any): Promise<Buffer | null> {
|
||||
console.log('[expenses/generate-pdf] Detected S3 URL, fetching directly...');
|
||||
|
||||
try {
|
||||
// Ensure URL is properly encoded
|
||||
let encodedUrl = rawPath;
|
||||
try {
|
||||
// Parse and reconstruct URL to ensure proper encoding
|
||||
const url = new URL(rawPath);
|
||||
// Re-encode the pathname to handle special characters
|
||||
url.pathname = url.pathname.split('/').map(segment => encodeURIComponent(decodeURIComponent(segment))).join('/');
|
||||
encodedUrl = url.toString();
|
||||
console.log('[expenses/generate-pdf] URL encoded:', encodedUrl);
|
||||
} catch (urlError) {
|
||||
console.log('[expenses/generate-pdf] Using original URL (encoding failed):', rawPath);
|
||||
encodedUrl = rawPath;
|
||||
}
|
||||
// Use the signed URL directly without modification to preserve AWS signature
|
||||
console.log('[expenses/generate-pdf] Fetching from S3 URL (preserving signature):', rawPath);
|
||||
|
||||
// Fetch image directly from S3 URL with proper headers
|
||||
const response = await fetch(encodedUrl, {
|
||||
// Fetch image directly from S3 URL with minimal headers to avoid signature issues
|
||||
const response = await fetch(rawPath, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'image/*',
|
||||
'User-Agent': 'PortNimara-Client-Portal/1.0',
|
||||
'Cache-Control': 'no-cache'
|
||||
'Accept': 'image/*'
|
||||
},
|
||||
// Add timeout to prevent hanging
|
||||
signal: AbortSignal.timeout(45000) // 45 second timeout
|
||||
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}`);
|
||||
console.error('[expenses/generate-pdf] Response headers:', Object.fromEntries(response.headers.entries()));
|
||||
|
||||
// Try with the original URL if encoding failed
|
||||
if (encodedUrl !== rawPath) {
|
||||
console.log('[expenses/generate-pdf] Retrying with original URL...');
|
||||
const originalResponse = await fetch(rawPath, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'image/*',
|
||||
'User-Agent': 'PortNimara-Client-Portal/1.0'
|
||||
},
|
||||
signal: AbortSignal.timeout(30000)
|
||||
});
|
||||
|
||||
if (originalResponse.ok) {
|
||||
const arrayBuffer = await originalResponse.arrayBuffer();
|
||||
const imageBuffer = Buffer.from(arrayBuffer);
|
||||
console.log('[expenses/generate-pdf] Successfully fetched with original URL, Size:', imageBuffer.length);
|
||||
return imageBuffer;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -810,27 +776,13 @@ async function fetchReceiptImage(receipt: any): Promise<Buffer | null> {
|
||||
|
||||
} catch (fetchError: any) {
|
||||
console.error('[expenses/generate-pdf] Error fetching from S3 URL:', fetchError.message);
|
||||
console.error('[expenses/generate-pdf] Error details:', {
|
||||
name: fetchError.name,
|
||||
code: fetchError.code,
|
||||
message: fetchError.message
|
||||
});
|
||||
|
||||
// If it's a timeout or network error, try one more time with simpler approach
|
||||
if (fetchError.name === 'TimeoutError' || fetchError.name === 'AbortError' || fetchError.code === 'ECONNRESET') {
|
||||
console.log('[expenses/generate-pdf] Network error, trying simplified approach...');
|
||||
try {
|
||||
const simpleResponse = await fetch(rawPath, {
|
||||
method: 'GET',
|
||||
signal: AbortSignal.timeout(90000) // Extended timeout for final attempt
|
||||
});
|
||||
|
||||
if (simpleResponse.ok) {
|
||||
const arrayBuffer = await simpleResponse.arrayBuffer();
|
||||
const imageBuffer = Buffer.from(arrayBuffer);
|
||||
console.log('[expenses/generate-pdf] Successfully fetched image with simplified approach, Size:', imageBuffer.length);
|
||||
return imageBuffer;
|
||||
}
|
||||
} catch (finalError) {
|
||||
console.error('[expenses/generate-pdf] Final attempt also failed:', finalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Don't try multiple attempts for signed URLs as they may expire
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user