fix(backend): improve ingestion error handling and error messages

This commit introduces a "force delete" mechanism for Ingestion Sources and improves error messages for file-based connectors.

Changes:
- Update `IngestionService.delete` to accept a `force` flag, bypassing the `checkDeletionEnabled` check.
- Use `force` deletion when rolling back failed ingestion source creations (e.g., decryption errors or connection failures) to ensure cleanup even if deletion is globally disabled.
- Enhance error messages in `EMLConnector`, `MboxConnector`, and `PSTConnector` to distinguish between missing local files and failed uploads, providing more specific feedback to the user.
This commit is contained in:
wayneshn
2026-02-24 12:15:49 +01:00
parent 7dac3b2bfd
commit 61f68ca9a6
4 changed files with 45 additions and 11 deletions

View File

@@ -85,7 +85,7 @@ export class IngestionService {
const decryptedSource = this.decryptSource(newSource);
if (!decryptedSource) {
await this.delete(newSource.id, actor, actorIp);
await this.delete(newSource.id, actor, actorIp, true);
throw new Error(
'Failed to process newly created ingestion source due to a decryption error.'
);
@@ -107,7 +107,7 @@ export class IngestionService {
}
} catch (error) {
// If connection fails, delete the newly created source and throw the error.
await this.delete(decryptedSource.id, actor, actorIp);
await this.delete(decryptedSource.id, actor, actorIp, true);
throw error;
}
}
@@ -205,8 +205,15 @@ export class IngestionService {
return decryptedSource;
}
public static async delete(id: string, actor: User, actorIp: string): Promise<IngestionSource> {
checkDeletionEnabled();
public static async delete(
id: string,
actor: User,
actorIp: string,
force: boolean = false
): Promise<IngestionSource> {
if (!force) {
checkDeletionEnabled();
}
const source = await this.findById(id);
if (!source) {
throw new Error('Ingestion source not found');

View File

@@ -58,7 +58,7 @@ export class EMLConnector implements IEmailConnector {
try {
const filePath = this.getFilePath();
if (!filePath) {
throw Error('EML file path not provided.');
throw Error('EML Zip file path not provided.');
}
if (!filePath.includes('.zip')) {
throw Error('Provided file is not in the ZIP format.');
@@ -77,12 +77,21 @@ export class EMLConnector implements IEmailConnector {
}
if (!fileExist) {
throw Error('EML file not found or upload not finished yet, please wait.');
if (this.credentials.localFilePath) {
throw Error(`EML Zip file not found at path: ${this.credentials.localFilePath}`);
} else {
throw Error(
'Uploaded EML Zip file not found. The upload may not have finished yet, or it failed.'
);
}
}
return true;
} catch (error) {
logger.error({ error, credentials: this.credentials }, 'EML file validation failed.');
logger.error(
{ error, credentials: this.credentials },
'EML Zip file validation failed.'
);
throw error;
}
}

View File

@@ -82,12 +82,21 @@ export class MboxConnector implements IEmailConnector {
}
if (!fileExist) {
throw Error('Mbox file not found or upload not finished yet, please wait.');
if (this.credentials.localFilePath) {
throw Error(`Mbox file not found at path: ${this.credentials.localFilePath}`);
} else {
throw Error(
'Uploaded Mbox file not found. The upload may not have finished yet, or it failed.'
);
}
}
return true;
} catch (error) {
logger.error({ error, credentials: this.credentials }, 'Mbox file validation failed.');
logger.error(
{ error, credentials: this.credentials },
'Mbox file validation failed.'
);
throw error;
}
}

View File

@@ -161,11 +161,20 @@ export class PSTConnector implements IEmailConnector {
}
if (!fileExist) {
throw Error('PST file not found or upload not finished yet, please wait.');
if (this.credentials.localFilePath) {
throw Error(`PST file not found at path: ${this.credentials.localFilePath}`);
} else {
throw Error(
'Uploaded PST file not found. The upload may not have finished yet, or it failed.'
);
}
}
return true;
} catch (error) {
logger.error({ error, credentials: this.credentials }, 'PST file validation failed.');
logger.error(
{ error, credentials: this.credentials },
'PST file validation failed.'
);
throw error;
}
}