Error handling for Mailer


#1

Trusting a mailer without error handling means hoping, that nothing breaks. Especially if the form data is not saved in the database (for reasons).

I digged a bit in the code and it looks like enabling error handling for the mailer is quite easy.

Changing $mail = new PHPMailer(); to $mail = new PHPMailer(true); in Mailer.php#L37 enables throwing Exceptions.

After changing Forms/bootstrap.php#L297 from

$this->app->mailer->mail($frm['email_forward'], $options['subject'] ?? "New form data for: {$formname}", $body, $options);

to

try {
    $response = $this->app->mailer->mail($frm['email_forward'], $options['subject'] ?? "New form data for: {$formname}", $body, $options);
} catch (\Exception $e) {
    $response = $e->getMessage();
}
if ($response !== true) {
    return ['error' => $response];
}

I get a useful response: {"error":"SMTP Error: Could not authenticate."}

That was easy. Now comes the hard part:

Changing the few places in core, where Mailer is called could be fixed easily. I think, the only mailings are password reset and form submission.

Throwing Exceptions could break all places where the Mailer was called without catching them. What if custom bootstraps or addons use the Mailer class?

The default for form submission is, to return $data. Should it return ['error' => $response, 'data' => $data] instead? This is the way, I handle form validation responses in FormValidation addon.


#2

I’m waiting for the Pull Request :wink:


#3

I’ll write it soon. I have a few things on my to do list with a higher priority:

  1. Custom renderers in entries view (set, maybe repeater, maybe some more)
  2. eplore new virtual assets folders to build an image gallery system
  3. change default tab in entry view to main
  4. Mailer Exceptions
  5. publish simple PHP frontend (using cockpit as a library)
  6. :wink: