Programmatically validate a node? I am programmatically creating many nodes. Obviously they have to be valid before storing them. Such $node objects have CCK fields mixed with custom fields.

Because the validators only set a form_set_error() and hardly ever return the validation-result, I have to go trough the form-api in order to know if a node is valid, or so it seems.

I call node_validate(), then form_get_errors() (which, in turn calls form_set_error()). 

There appear to be several problems with this approach: 


form_set_error() sets a message with drupal_set_message(); for stuff like cron (a session-less user), this adds orphaned persistent error-messages to the database (they will never be printed, hence never deleted).
the returning array of errors is created to be used in a multidimensional form array. Especially with CCK-fields, I have to dig quite deep in order to find the actual error. 
I just want to store a node, so I am not interested in a user-faced form; using the form API just feels wrong.


Is there a simpler, more elegant method?
There aren't any other ways, as the hooks that the modules need to implement to validate a node are hook_validate() (if the module implements a content type) and hook_nodeapi('validate') (for all the other modules). Those hooks get a $form parameter, and are supposed to call form_set_error() in the case there is a validation error.

The easier way to find if there are errors set for a form is to use form_get_errors(), which returns the array with all the errors set with form_set_error(), the function that is also called from form_error().

In the case more than one node is validated, you would need to call form_set_error(NULL, '', TRUE) before node_validate(), and then get from form_get_errors() the array containing the error messages; if this is empty, there are no error messages.

form_set_error(NULL, '', TRUE);

// node_validate() call.

$errors = form_get_errors();

if (!empty($errors)) {
  // Some module reported an error.
}


Alternatively, you can use the following snippet to verify no module reported an error, after you call node_validate():

if (!empty($_SESSION['messages']['error'])) {
  // Some module reported an error.
}


Before calling node_validate() from the cron task, you would need to set $_SESSION['messages']['error'] to an empty array; in that way, you are sure the errors reported in the array are caused by the node validation hooks.

$_SESSION['messages'] is the variable used from drupal_set_message() to store the messages passed to the function.

function drupal_set_message($message = NULL, $type = 'status', $repeat = TRUE) {
  if ($message) {
    if (!isset($_SESSION['messages'])) {
      $_SESSION['messages'] = array();
    }

    if (!isset($_SESSION['messages'][$type])) {
      $_SESSION['messages'][$type] = array();
    }
    // …
  }
  // …
}