Score:0

cURL request causing form validation error

in flag

I'm working on a cURL request when a user submits an existing form to send some data to an outside service.

I've added this function with this line: $form['actions'][$action]['#submit'][] = 'my_module_push_data';

And my cURL requests:

    $ch = curl_init();
    // Get access token here
    curl_setopt($ch, CURLOPT_URL, 'https://resturl.com&id=' . $id . '&secret=' . $secret);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $result = curl_exec($ch);
    curl_close($ch);
    $result = json_decode($result, true);

    // Then submit data
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'https://resturl.com/submit.json?access_token=' . $result['access_token']);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($formData));
    curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $server_output = curl_exec($ch); // <--- This line causes issues
    $server_output = json_decode($server_output);

With this code, I'm getting this error:

Uncaught PHP Exception LogicException: "Form errors cannot be set after form validation has finished." at /mnt/gfs/.../.../docroot/core/lib/Drupal/Core/Form/FormState.php

I've gone line by line through this cURL request and the line I marked (second curl_exec() causes this error. If I omit that line it works fine. The first curl_exec() works fine and I verified it's returning an access token.

What am I doing wrong here? Thank you!

EDIT: Full function (obfuscated some details)

/**
 * Custom submit handler to push data into Service
 */
function my_module_service_signup(array $form, \Drupal\Core\Form\FormStateInterface $form_state) {
    $vals = $form_state->getValues();
    $formData = [];
    $myVals = [];

    $clientId = Settings::get('service_api_id');
    $clientSecret = Settings::get('service_api_secret');
    $accountId = 'abc123456';
    $formData['unique_id'] = '1234';

    $myVals = [
        'company' => $vals['field_company'][0]['value'],
        'firstName' => $vals['field_first_name'][0]['value'],
        'lastName' => $vals['field_last_name'][0]['value'],
        ...
    ];

    $formData['input'][0]['fields'] = $myVals;

    try {
        $getClient = \Drupal::httpClient();
        $request = $getClient->post('https://' . $accountId . '.resturl.com/get/token?my_id=' . $clientId . '&my_secret=' . $clientSecret);
        $response = json_decode($request->getBody());
    } catch(RequestException $e) {
    // The LogicException is not caught here
    }
}

Jaypan avatar
de flag
You need to show us the function that code exists in. Also, Drupal uses the Guzzle HTTP client for remote requests, which can be accessed with `\Drupal::httpClient()`.
in flag
@Jaypan I've made an edit with the full function (with some private details changed). I tried switching to using `\Drupal::httpClient()` this morning and it throws the same error. It seems to only throw the error when it receives a successful response from the endpoint. I'm able to see the response body in watchdog but it continues to throw this exception.
Jaypan avatar
de flag
Are you sure that's where your error is coming from? What happens if you remove the request altogether just for testing?
in flag
@Jaypan Everything works fine if the request is removed. No errors logged in watchdog, the user account is created and the user is redirected to the backend of the site. Just commenting out the line with `$getClient->post()` resolves the issue.
Jaypan avatar
de flag
Try catching `\Exception`, then using `watchdog_exception()` (https://api.drupal.org/api/drupal/core%21includes%21bootstrap.inc/function/watchdog_exception/9.2.x) to log the result. Maybe you can get more information from that.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.