feat: Enhance error handling and logging in expense and interest duplicate detection, add retry logic for document deletion, and improve PDF generation with detailed receipt processing
This commit is contained in:
@@ -12,6 +12,7 @@ export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const body = await readBody(event);
|
||||
const { interestId } = body;
|
||||
const query = getQuery(event);
|
||||
|
||||
console.log('[Delete Generated EOI] Interest ID:', interestId);
|
||||
|
||||
@@ -77,51 +78,132 @@ export default defineEventHandler(async (event) => {
|
||||
|
||||
console.log('[Delete Generated EOI] Deleting document from Documenso');
|
||||
let documensoDeleteSuccessful = false;
|
||||
let retryCount = 0;
|
||||
const maxRetries = 3;
|
||||
|
||||
try {
|
||||
const deleteResponse = await fetch(`${documensoBaseUrl}/api/v1/documents/${documensoID}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${documensoApiKey}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
// Retry logic for temporary failures
|
||||
while (!documensoDeleteSuccessful && retryCount < maxRetries) {
|
||||
try {
|
||||
const deleteResponse = await fetch(`${documensoBaseUrl}/api/v1/documents/${documensoID}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${documensoApiKey}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
if (!deleteResponse.ok) {
|
||||
const errorText = await deleteResponse.text();
|
||||
console.error('[Delete Generated EOI] Documenso deletion failed:', errorText);
|
||||
const responseStatus = deleteResponse.status;
|
||||
let errorDetails = '';
|
||||
|
||||
// If it's a 404, the document is already gone, which is what we want
|
||||
if (deleteResponse.status === 404) {
|
||||
console.log('[Delete Generated EOI] Document already deleted from Documenso (404) - proceeding with database cleanup');
|
||||
documensoDeleteSuccessful = true;
|
||||
} else {
|
||||
throw new Error(`Failed to delete document from Documenso: ${deleteResponse.statusText}`);
|
||||
try {
|
||||
errorDetails = await deleteResponse.text();
|
||||
} catch {
|
||||
errorDetails = 'No error details available';
|
||||
}
|
||||
} else {
|
||||
console.log('[Delete Generated EOI] Successfully deleted document from Documenso');
|
||||
documensoDeleteSuccessful = true;
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error('[Delete Generated EOI] Documenso deletion error:', error);
|
||||
|
||||
// Check if it's a network error or 404 - in those cases, proceed with cleanup
|
||||
if (error.message?.includes('404') || error.status === 404) {
|
||||
console.log('[Delete Generated EOI] Document not found in Documenso - proceeding with database cleanup');
|
||||
documensoDeleteSuccessful = true;
|
||||
} else {
|
||||
|
||||
if (!deleteResponse.ok) {
|
||||
console.error(`[Delete Generated EOI] Documenso deletion failed (attempt ${retryCount + 1}/${maxRetries}):`, {
|
||||
status: responseStatus,
|
||||
statusText: deleteResponse.statusText,
|
||||
details: errorDetails
|
||||
});
|
||||
|
||||
// Handle specific status codes
|
||||
switch (responseStatus) {
|
||||
case 404:
|
||||
// Document already deleted - this is fine
|
||||
console.log('[Delete Generated EOI] Document already deleted from Documenso (404) - proceeding with database cleanup');
|
||||
documensoDeleteSuccessful = true;
|
||||
break;
|
||||
|
||||
case 403:
|
||||
// Permission denied - document might be in a protected state
|
||||
console.warn('[Delete Generated EOI] Permission denied (403) - document may be in a protected state');
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: 'Cannot delete document - it may be fully signed or in a protected state',
|
||||
});
|
||||
|
||||
case 500:
|
||||
case 502:
|
||||
case 503:
|
||||
case 504:
|
||||
// Server errors - retry if we haven't exceeded retries
|
||||
if (retryCount < maxRetries - 1) {
|
||||
console.log(`[Delete Generated EOI] Server error (${responseStatus}) - retrying in ${(retryCount + 1) * 2} seconds...`);
|
||||
await new Promise(resolve => setTimeout(resolve, (retryCount + 1) * 2000)); // Exponential backoff
|
||||
retryCount++;
|
||||
continue;
|
||||
} else {
|
||||
console.error('[Delete Generated EOI] Max retries exceeded for server error');
|
||||
// Allow proceeding with cleanup for server errors after retries
|
||||
if (query.forceCleanup === 'true') {
|
||||
console.warn('[Delete Generated EOI] Force cleanup enabled - proceeding despite Documenso error');
|
||||
documensoDeleteSuccessful = true;
|
||||
break;
|
||||
}
|
||||
throw new Error(`Documenso server error after ${maxRetries} attempts (${responseStatus}): ${errorDetails}`);
|
||||
}
|
||||
|
||||
default:
|
||||
// Other errors - don't retry
|
||||
throw new Error(`Documenso API error (${responseStatus}): ${errorDetails || deleteResponse.statusText}`);
|
||||
}
|
||||
} else {
|
||||
console.log('[Delete Generated EOI] Successfully deleted document from Documenso');
|
||||
documensoDeleteSuccessful = true;
|
||||
}
|
||||
} catch (error: any) {
|
||||
console.error(`[Delete Generated EOI] Documenso deletion error (attempt ${retryCount + 1}/${maxRetries}):`, error);
|
||||
|
||||
// Network errors - retry if we haven't exceeded retries
|
||||
if (error.code === 'ECONNREFUSED' || error.code === 'ETIMEDOUT' || error.code === 'ENOTFOUND') {
|
||||
if (retryCount < maxRetries - 1) {
|
||||
console.log(`[Delete Generated EOI] Network error - retrying in ${(retryCount + 1) * 2} seconds...`);
|
||||
await new Promise(resolve => setTimeout(resolve, (retryCount + 1) * 2000));
|
||||
retryCount++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if it's a 404 error wrapped in another error
|
||||
if (error.message?.includes('404') || error.status === 404 || error.statusCode === 404) {
|
||||
console.log('[Delete Generated EOI] Document not found in Documenso - proceeding with database cleanup');
|
||||
documensoDeleteSuccessful = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if force cleanup is enabled
|
||||
const query = getQuery(event);
|
||||
if (query.forceCleanup === 'true') {
|
||||
console.warn('[Delete Generated EOI] Force cleanup enabled - proceeding despite Documenso error:', error.message);
|
||||
documensoDeleteSuccessful = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// Don't wrap error messages multiple times
|
||||
if (error.statusCode) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: `Failed to delete document from Documenso: ${error.message}`,
|
||||
statusMessage: error.message || 'Failed to communicate with Documenso API',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!documensoDeleteSuccessful) {
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Failed to delete document from Documenso',
|
||||
});
|
||||
const query = getQuery(event);
|
||||
if (query.forceCleanup === 'true') {
|
||||
console.warn('[Delete Generated EOI] Force cleanup enabled - proceeding with database cleanup despite Documenso failure');
|
||||
documensoDeleteSuccessful = true;
|
||||
} else {
|
||||
throw createError({
|
||||
statusCode: 500,
|
||||
statusMessage: 'Failed to delete document from Documenso after multiple attempts. You can add ?forceCleanup=true to force database cleanup.',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Reset interest fields
|
||||
|
||||
Reference in New Issue
Block a user