All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 19m20s
106 lines
3.3 KiB
TypeScript
106 lines
3.3 KiB
TypeScript
// src/services/processingErrors.ts
|
|
|
|
/**
|
|
* Base class for all flyer processing errors.
|
|
* This allows for catching all processing-related errors with a single `catch` block.
|
|
* Each custom error should define its own `errorCode` and a user-friendly `message`.
|
|
*/
|
|
export class FlyerProcessingError extends Error {
|
|
public errorCode: string;
|
|
public userMessage: string;
|
|
|
|
constructor(message: string, errorCode: string = 'UNKNOWN_ERROR', userMessage?: string) {
|
|
super(message); // The 'message' property of Error is for internal/developer use.
|
|
this.name = this.constructor.name;
|
|
this.errorCode = errorCode;
|
|
this.userMessage = userMessage || message; // User-friendly message for UI
|
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
}
|
|
|
|
toErrorPayload(): { errorCode: string; message: string; [key: string]: any } {
|
|
return { errorCode: this.errorCode, message: this.userMessage };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Error thrown when PDF to image conversion fails (e.g., pdftocairo produces no output).
|
|
*/
|
|
export class PdfConversionError extends FlyerProcessingError {
|
|
public stderr?: string;
|
|
constructor(message: string, stderr?: string) {
|
|
super(
|
|
message,
|
|
'PDF_CONVERSION_FAILED',
|
|
'The uploaded PDF could not be processed. It might be blank, corrupt, or password-protected.',
|
|
);
|
|
this.stderr = stderr;
|
|
}
|
|
|
|
toErrorPayload(): { errorCode: string; message: string; [key: string]: any } {
|
|
return { ...super.toErrorPayload(), stderr: this.stderr };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Error thrown when the data returned from the AI service fails Zod validation.
|
|
*/
|
|
export class AiDataValidationError extends FlyerProcessingError {
|
|
constructor(
|
|
message: string,
|
|
public validationErrors: object,
|
|
public rawData: unknown,
|
|
) {
|
|
super(
|
|
message,
|
|
'AI_VALIDATION_FAILED',
|
|
"The AI couldn't read the flyer's format. Please try a clearer image or a different flyer.",
|
|
);
|
|
}
|
|
|
|
toErrorPayload(): { errorCode: string; message: string; [key: string]: any } {
|
|
return { ...super.toErrorPayload(), validationErrors: this.validationErrors, rawData: this.rawData };
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Error thrown when a transformation step fails.
|
|
*/
|
|
export class TransformationError extends FlyerProcessingError {
|
|
constructor(message: string) {
|
|
super(
|
|
message,
|
|
'TRANSFORMATION_FAILED',
|
|
'There was a problem transforming the flyer data. Please check the input.',
|
|
);
|
|
}
|
|
}
|
|
/**
|
|
* Error thrown when an image conversion fails (e.g., using sharp).
|
|
*/
|
|
export class ImageConversionError extends FlyerProcessingError {
|
|
constructor(message: string) {
|
|
super(
|
|
message,
|
|
'IMAGE_CONVERSION_FAILED',
|
|
'The uploaded image could not be processed. It might be corrupt or in an unsupported format.',
|
|
);
|
|
}
|
|
}
|
|
/**
|
|
* Error thrown when all geocoding providers fail to find coordinates for an address.
|
|
*/
|
|
export class GeocodingFailedError extends FlyerProcessingError {
|
|
constructor(message: string) {
|
|
super(message, 'GEOCODING_FAILED', 'Failed to geocode the address.');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Error thrown when an uploaded file is of an unsupported type (e.g., .gif, .tiff).
|
|
*/
|
|
export class UnsupportedFileTypeError extends FlyerProcessingError {
|
|
constructor(message: string) {
|
|
super(message, 'UNSUPPORTED_FILE_TYPE', message); // The message is already user-friendly.
|
|
}
|
|
}
|