Prevent node from being saved in hook_node_presave When saving / updating node, i need to validate if certain fields combination is unique. Unique field module is supposed to allow this, but that feature is not working (validating only single field). So i created my own hook:

function mymodule_node_presave(\Drupal\Core\Entity\EntityInterface $node) {

  if ($node-&gt;bundle() == 'mycontent') {

    $term = \Drupal\taxonomy\Entity\Term::load($node-&gt;get('field_mytaxonomy')-&gt;target_id);

    $query = \Drupal::entityQuery('node');
    $query-&gt;condition('type', 'mycontent');
    $query-&gt;condition('field_mydate', $node-&gt;get('field_mydate')-&gt;value, '=');
    $query-&gt;condition('field_mytaxonomy', $term-&gt;id(), '=');

    $nids = $query-&gt;execute();

    if ($nids) {
      drupal_set_message('Fields are not unique!', 'error');
      // I need to prevent saving of node here      
    }  
  }
}


Detection of node with duplicite values being created works. How do i prevent saving that node?
How do i prevent saving that node?

If you want to prevent that the node is saved in a presave method or hook you have to throw an exception:

throw new \Exception(t('Fields are not unique!'));


More user friendly would be to check this in the form first and give the user a chance to correct the input before you throw an exception.

Double checking this in presave is still a good idea to make sure, that no incorrect node content gets saved, no matter which form, Rest API or code is used. If someone gets past the first level of checks in the form you have no other option than to throw an exception.

Edit:

In case an exception is raised, you can replace the default 500 response with a custom error handling in an exception subscriber, see Handle database connection exception via custom handler