Mail Exceptions¶
Mail helpers rely on a focused hierarchy rooted at MailError.
Each subclass narrows the failure domain so you can tell validation issues apart from transport or configuration gaps.
Import everything from kstlib.mail.exceptions to keep guards close to the rest of the mail API.
Exception Hierarchy¶
MailError
├── MailValidationError # Invalid recipients, attachments
├── MailTransportError # SMTP/transport delivery failure
├── MailConfigurationError # Missing headers, secrets, templates
└── MailThrottledError # Throttle bucket empty, on_exceed='raise'
Note
Filesystem guardrails never bypass the operating system. They provide a consistent abstraction for attachment, inline, and template paths, but you still need to provision directories and permissions at the OS level.
Quick overview¶
MailErroris the catch-all when you need to terminate a workflow regardless of the root cause.MailValidationErrorreports missing recipients, malformed addresses, unsupported attachments, or guardrail violations detected byMailBuilderandMailFilesystemGuards.MailTransportErrorsurfaces when the active backend (filesystem spool, SMTP, future providers) rejects or times out a delivery attempt.MailConfigurationErroris raised when required headers, secrets, or templates are missing at build time.MailThrottledErroris raised whenMailThrottleblocks a send because the token-bucket is empty and the configuredon_exceedmode is"raise". Carries throttle parameters in its message to help the caller pick a backoff strategy.
Usage patterns¶
Building messages defensively¶
from kstlib.mail import MailBuilder
from kstlib.mail.exceptions import MailConfigurationError, MailValidationError
builder = MailBuilder()
try:
builder.set_sender("alerts@example.com")
builder.add_recipient("ops@example.com")
builder.set_subject("Heartbeat failed")
message = builder.build()
except MailConfigurationError as error:
raise SystemExit(f"Missing mail configuration: {error}") from error
except MailValidationError as error:
LOGGER.warning("Mail rejected by validators", error=error)
Handling transport fallbacks¶
from kstlib.mail.transports.smtp import SMTPTransport, SMTPCredentials
from kstlib.mail.exceptions import MailTransportError
transport = SMTPTransport(
host="smtp.example.com",
credentials=SMTPCredentials(username="alerts", password="secret"),
)
try:
transport.send(message)
except MailTransportError:
backup = SMTPTransport(host="smtp-backup.example.com")
backup.send(message)
Module reference¶
Custom exceptions for the mail module.
- exception kstlib.mail.exceptions.MailConfigurationError[source]
Bases:
MailErrorRaised when the mail builder is missing required configuration.
- exception kstlib.mail.exceptions.MailError[source]
Bases:
KstlibErrorBase class for mail related errors.
- exception kstlib.mail.exceptions.MailThrottledError[source]
Bases:
MailErrorRaised when the mail throttle bucket is empty and on_exceed is ‘raise’.
Carries the throttle parameters in the message to help the caller decide on a backoff strategy. The throttle is config-driven via
mail.throttle.*and acts as an anti-spam kill switch.See also
kstlib.mail.MailThrottle
- exception kstlib.mail.exceptions.MailTransportError[source]
Bases:
MailErrorRaised when a transport backend cannot deliver a message.
- exception kstlib.mail.exceptions.MailValidationError[source]
Bases:
MailErrorRaised when provided mail data fails validation checks.