Skip to content
Grav 2.0 is officially stable. Read the announcement →

Community guidelines

Please keep discussions civil and on-topic. Repeated violations may lead to a temporary ban.

Plugins

Correctly handling errors from custom form processes

Started by Richard Hainsworth 8 years ago · 0 replies · 603 views
8 years ago

I have written (and published) grav-plugin-sqlite and grav-plugin-sequential-form.

Both work well, but not in combination when there is an error.

For example, if a sequential-form is created in an sequence.md file (a sequential-form being an extension of a standard form) with the processes:

YAML
# yaml for the start of the form with buttons and fields as standard
 process:
    - sequence:
          routes:
              - video # a route to sequence.md
              - terms # a route to sequence.md
          icons:
              - address-card
              - video-camera
              - thumbs-up
    - sql-insert:
        table: clients
    - redirect: register/final

The sequence process is defined in the sequential-form plugin, and completes without a problem.

The sql-insert process is defined in the sqlite plugin. However, the SQL INSERT stanza (not shown here) that is generated fails (in my specific case, which is not relevant here, the failure occurs because the SQL table is defined with a UNIQUE constraint that is broken by the data input into the form). The point is that the failure is due to input data, and so should be trapped for the User to know there is an error in the data.

The sqlite plugin correctly traps the error, but I cannot work out how to output the error in the form when there are multiple processes, as here.

So in the sqlite plugin, within the function 'onFormProcessed' in the section where sql-insert is processed, I have:

PHP
$sql ="INSERT INTO {$params['table']} ( $fields ) VALUES ( $values )";
$db = $this->grav['sqlite']['db'];
try {
  $db->exec($sql) ;
} catch ( \Exception $e ) {
  $msg = $e->getMessage();
  if ( stripos($msg, 'unique') !== false ) {
    $msg .= $this->grav['language']->translate(['PLUGIN_SQLITE.UNIQUE_FIELD_ERROR']);
  } else {
     $msg .= $this->grav['language']->translate(['PLUGIN_SQLITE.OTHER_SQL_ERROR']) . "<BR>$sql";
  }
  if ($this->grav['sqlite']['logging']) {
    $this->log_error($msg); # a function that appends the $msg string to a file
    $this->log_error(print_r($event['form'],true));
  }
  $this->grav->fireEvent('onFormValidationError', new Event([
    'form'    => $event['form'],
    'message' => $msg
  ]));
  $event->stopPropagation();
}

When sql-insert is the first process in the form, then the error message is displayed in the form, and propagation stops, as documented for the Form plugin.

In this case, however, when an error is generated by sql-insert, GRAV completely fails because the form's sequence process gets called again. The error is generated within the template sequence.html.twig.

I cannot see why $event->stopPropagation() is not stopping the form processing.

When I trap $event['form'] with the log function, the Form process array starts with sql-insert, which is what I would expect. But why is the form being processed from the beginning?

Any pointers as how I should be handling the error trapped by sqlite?

last edited 06/22/18 by Richard Hainsworth

Suggested topics

Topic Participants Replies Views Activity
Plugins · by Rene, 1 week ago
2 49 1 week ago
Plugins · by Xavier, 4 weeks ago
2 57 4 weeks ago
Plugins · by Luka Prinčič, 7 years ago
3 1184 1 month ago
Plugins · by Sebastian van de Meer, 1 month ago
1 50 1 month ago
Plugins · by PIERROT Alain, 2 months ago
3 75 2 months ago