What is the proper way to show a visitor an error? I'm using a custom submit handler for a Webform, which POSTs important form data to another API. That part works, but on occasion there may be random network errors that prevent a successful submission, such as if the REST endpoint happened to be down at that particular moment (or whatever).

In those cases, I don't want the user to think their form successfully submitted when it didn't. How can I override the confirmation page with a custom error page? I tried drupal_set_message(), but it doesn't show up anywhere on the confirmation page that I could see.

Ideally, I would also be able to get back the event ID generated by watchdog logging so that the user, if they contact us by phone or email upon seeing the error, would be able to provide more information that can help us debug it.

So in summary, in a perfect world, a failed submission would result in:


The form submission ($form_state) being logged into watchdog or another log
Watchdog returns the associated event ID
The user sees a custom error page describing the error, with the event ID as an error code to help in debugging.


I can hack something together with die() and a hash of the form data as an error code, but is there a better, proper Drupal way?

Relevant code so far:

 try {
    $apiResponse = drupal_http_request($apiEndPoint, [
      'headers' =&gt; ['Content-Type' =&gt; 'application/json'],
      'method' =&gt; 'POST',
      'data' =&gt; drupal_json_encode($formData),
      'timeout' =&gt; 5 // Timeout in seconds.
    ]);

    // I'm not okay :(
    if ($apiResponse-&gt;code != "200") {
      throw new Exception ($apiResponse-&gt;data, $apiResponse-&gt;code);
    }
  } catch (Throwable $e) {
    watchdog('tfm_custom_form_handlers', "A custom form handler failed: (@code) @message.", [
      '@code' =&gt; $e-&gt;getCode(),
      '@message' =&gt; $e-&gt;getMessage(),
    ], WATCHDOG_ERROR);
  }


Thanks for the help!
Have your POST code inside a validate function, that runs last, after all other validation has passed.

Ex: $form['submit']['#validate'][] = 'mymodule_post_to_api';

and use form_set_error('form', 'Failed to connect to API, try again later'); inside your catch.

For POST's errors, don't wait for someone to report. Programmatically make Drupal send yourself or whomever maintains the code, an e-mail with the form fields &amp; error details. 

See How to programmatically send an email?