update
This commit is contained in:
313
ts/errors/email.errors.ts
Normal file
313
ts/errors/email.errors.ts
Normal file
@@ -0,0 +1,313 @@
|
||||
import {
|
||||
PlatformError,
|
||||
ValidationError,
|
||||
NetworkError,
|
||||
ResourceError,
|
||||
OperationError
|
||||
} from './base.errors.js';
|
||||
import type { IErrorContext } from './base.errors.js';
|
||||
|
||||
import {
|
||||
EMAIL_SERVICE_ERROR,
|
||||
EMAIL_TEMPLATE_ERROR,
|
||||
EMAIL_VALIDATION_ERROR,
|
||||
EMAIL_SEND_ERROR,
|
||||
EMAIL_RECEIVE_ERROR,
|
||||
EMAIL_ATTACHMENT_ERROR,
|
||||
EMAIL_PARSE_ERROR,
|
||||
EMAIL_RATE_LIMIT_EXCEEDED
|
||||
} from './error.codes.js';
|
||||
|
||||
/**
|
||||
* Base class for all email service related errors
|
||||
*/
|
||||
export class EmailServiceError extends OperationError {
|
||||
/**
|
||||
* Creates a new email service error
|
||||
*
|
||||
* @param message Error message
|
||||
* @param context Additional context
|
||||
*/
|
||||
constructor(
|
||||
message: string,
|
||||
context: IErrorContext = {}
|
||||
) {
|
||||
super(message, EMAIL_SERVICE_ERROR, context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error class for email template errors
|
||||
*/
|
||||
export class EmailTemplateError extends OperationError {
|
||||
/**
|
||||
* Creates a new email template error
|
||||
*
|
||||
* @param message Error message
|
||||
* @param context Additional context
|
||||
*/
|
||||
constructor(
|
||||
message: string,
|
||||
context: IErrorContext = {}
|
||||
) {
|
||||
super(message, EMAIL_TEMPLATE_ERROR, context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error class for email validation errors
|
||||
*/
|
||||
export class EmailValidationError extends ValidationError {
|
||||
/**
|
||||
* Creates a new email validation error
|
||||
*
|
||||
* @param message Error message
|
||||
* @param context Additional context
|
||||
*/
|
||||
constructor(
|
||||
message: string,
|
||||
context: IErrorContext = {}
|
||||
) {
|
||||
super(message, EMAIL_VALIDATION_ERROR, context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error class for email sending errors
|
||||
*/
|
||||
export class EmailSendError extends OperationError {
|
||||
/**
|
||||
* Creates a new email send error
|
||||
*
|
||||
* @param message Error message
|
||||
* @param context Additional context
|
||||
*/
|
||||
constructor(
|
||||
message: string,
|
||||
context: IErrorContext = {}
|
||||
) {
|
||||
super(message, EMAIL_SEND_ERROR, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance for a permanently failed send
|
||||
*
|
||||
* @param message Error message
|
||||
* @param context Additional context
|
||||
*/
|
||||
public static permanent(
|
||||
message: string,
|
||||
context: IErrorContext = {}
|
||||
): EmailSendError {
|
||||
return new EmailSendError(`Permanent send failure: ${message}`, {
|
||||
...context,
|
||||
data: {
|
||||
...context.data,
|
||||
permanent: true
|
||||
},
|
||||
userMessage: 'The email could not be delivered due to a permanent failure.'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance for a temporary failed send
|
||||
*
|
||||
* @param message Error message
|
||||
* @param maxRetries Maximum number of retries
|
||||
* @param currentRetry Current retry count
|
||||
* @param retryDelay Delay between retries in ms
|
||||
* @param context Additional context
|
||||
*/
|
||||
public static temporary(
|
||||
message: string,
|
||||
maxRetries: number = 3,
|
||||
currentRetry: number = 0,
|
||||
retryDelay: number = 60000,
|
||||
context: IErrorContext = {}
|
||||
): EmailSendError {
|
||||
const error = new EmailSendError(`Temporary send failure: ${message}`, {
|
||||
...context,
|
||||
data: {
|
||||
...context.data,
|
||||
permanent: false
|
||||
},
|
||||
userMessage: 'The email delivery failed temporarily. It will be retried.'
|
||||
});
|
||||
|
||||
return error.withRetry(maxRetries, currentRetry, retryDelay) as EmailSendError;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this is a permanent send failure
|
||||
*/
|
||||
public isPermanent(): boolean {
|
||||
return !!this.context.data?.permanent;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error class for email receiving errors
|
||||
*/
|
||||
export class EmailReceiveError extends OperationError {
|
||||
/**
|
||||
* Creates a new email receive error
|
||||
*
|
||||
* @param message Error message
|
||||
* @param context Additional context
|
||||
*/
|
||||
constructor(
|
||||
message: string,
|
||||
context: IErrorContext = {}
|
||||
) {
|
||||
super(message, EMAIL_RECEIVE_ERROR, context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error class for email attachment errors
|
||||
*/
|
||||
export class EmailAttachmentError extends ValidationError {
|
||||
/**
|
||||
* Creates a new email attachment error
|
||||
*
|
||||
* @param message Error message
|
||||
* @param context Additional context
|
||||
*/
|
||||
constructor(
|
||||
message: string,
|
||||
context: IErrorContext = {}
|
||||
) {
|
||||
super(message, EMAIL_ATTACHMENT_ERROR, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance for an attachment too large error
|
||||
*
|
||||
* @param size Attachment size in bytes
|
||||
* @param maxSize Maximum allowed size in bytes
|
||||
* @param filename Attachment filename
|
||||
* @param context Additional context
|
||||
*/
|
||||
public static tooLarge(
|
||||
size: number,
|
||||
maxSize: number,
|
||||
filename?: string,
|
||||
context: IErrorContext = {}
|
||||
): EmailAttachmentError {
|
||||
const filenameText = filename ? ` (${filename})` : '';
|
||||
return new EmailAttachmentError(
|
||||
`Attachment${filenameText} size ${size} bytes exceeds maximum allowed size of ${maxSize} bytes`,
|
||||
{
|
||||
...context,
|
||||
data: {
|
||||
...context.data,
|
||||
size,
|
||||
maxSize,
|
||||
filename
|
||||
},
|
||||
userMessage: `The attachment${filenameText} is too large. Maximum size is ${Math.round(maxSize / 1024 / 1024)} MB.`
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance for an invalid attachment type error
|
||||
*
|
||||
* @param contentType Attachment content type
|
||||
* @param filename Attachment filename
|
||||
* @param allowedTypes List of allowed content types
|
||||
* @param context Additional context
|
||||
*/
|
||||
public static invalidType(
|
||||
contentType: string,
|
||||
filename: string,
|
||||
allowedTypes: string[],
|
||||
context: IErrorContext = {}
|
||||
): EmailAttachmentError {
|
||||
return new EmailAttachmentError(
|
||||
`Attachment '${filename}' with content type '${contentType}' is not allowed. Allowed types: ${allowedTypes.join(', ')}`,
|
||||
{
|
||||
...context,
|
||||
data: {
|
||||
...context.data,
|
||||
contentType,
|
||||
filename,
|
||||
allowedTypes
|
||||
},
|
||||
userMessage: `The attachment type ${contentType} is not allowed.`
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error class for email parsing errors
|
||||
*/
|
||||
export class EmailParseError extends OperationError {
|
||||
/**
|
||||
* Creates a new email parse error
|
||||
*
|
||||
* @param message Error message
|
||||
* @param context Additional context
|
||||
*/
|
||||
constructor(
|
||||
message: string,
|
||||
context: IErrorContext = {}
|
||||
) {
|
||||
super(message, EMAIL_PARSE_ERROR, context);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Error class for email rate limit exceeded errors
|
||||
*/
|
||||
export class EmailRateLimitError extends ResourceError {
|
||||
/**
|
||||
* Creates a new email rate limit error
|
||||
*
|
||||
* @param message Error message
|
||||
* @param context Additional context
|
||||
*/
|
||||
constructor(
|
||||
message: string,
|
||||
context: IErrorContext = {}
|
||||
) {
|
||||
super(message, EMAIL_RATE_LIMIT_EXCEEDED, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an instance with rate limit information
|
||||
*
|
||||
* @param limit Rate limit
|
||||
* @param remaining Remaining quota
|
||||
* @param resetAt Time when the quota resets
|
||||
* @param scope Rate limit scope (global, domain, user, etc.)
|
||||
* @param context Additional context
|
||||
*/
|
||||
public static withLimitInfo(
|
||||
limit: number,
|
||||
remaining: number,
|
||||
resetAt: Date | number,
|
||||
scope: string = 'global',
|
||||
context: IErrorContext = {}
|
||||
): EmailRateLimitError {
|
||||
const resetTime = typeof resetAt === 'number' ? new Date(resetAt) : resetAt;
|
||||
const resetTimeStr = resetTime.toISOString();
|
||||
|
||||
return new EmailRateLimitError(
|
||||
`Email rate limit exceeded: ${remaining}/${limit} remaining in ${scope} scope, resets at ${resetTimeStr}`,
|
||||
{
|
||||
...context,
|
||||
data: {
|
||||
...context.data,
|
||||
limit,
|
||||
remaining,
|
||||
resetAt: resetTime.getTime(),
|
||||
resetTimeStr,
|
||||
scope
|
||||
},
|
||||
userMessage: `You've reached the email sending limit. Please try again later.`
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user