I have a function deployed to my appwrite 1.3.7 server. Right now, it just sends an email using PHPMailer. It works (triggered by my clicking the Execute now button in the web console) exactly half the time, and the successes and failures always occur back to back. If it fails one execution, it will succeed the next and vice versa. What is causing this strange behavior?
#An internal curl error has occurred within the executor! Error Msg: Operation timed out
1 messages · Page 1 of 1 (latest)
Maybe some code is throwing an exception
This wouldn't explain the strange cyclical behavior of the successes and failures. I can't seem to get it to display any logging. I don't see any evidence it runs at all when the execution is due to fail.
i removed the email code and the cyclical nature of completing and failing remains. The evidence is that appwrite runs the function half the time and the other half, it summarily claims it did without actually running it.
Can you share your code?
I have barebones the code ```<?php
require 'vendor/autoload.php';
use Appwrite\Client;
use Appwrite\Services\Databases;
use Appwrite\Query;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
return function ($req, $res) {
$api_key = $req['variables']['API_KEY'];
$mailError = "No error";
$res->json([
'message' => $mailError,
]);
}
?>
how is this being executed and what's the timing between them?
are there any logs in the function execution, executor container, or runtime container?
have you tried wrapping everything in the function block with a try/catch and making sure to always call res->json() or res->send() exactly once?
I am clicking the Execute Now button in the web console. After an execution has completed, pass or fail, I click it again. Or I may wait a while. It doesn't matter. It always follows this cyclical pattern of failing and succeeding. Here is the output of the executor ```Executing Runtime: 648fc20504d0ed7a089d-650d2eac4a366015431a
Function executed in 0.0063409805297852 seconds, status: completed
Executing Runtime: 648fc20504d0ed7a089d-650d2eac4a366015431a
[Error] Type: Exception
[Error] Message: An internal curl error has occurred within the executor! Error Msg: Operation timed out
[Error] File: /usr/src/code/app/executor.php
[Error] Line: 544
I bareboned the function to just assign variables, not sure if there is anything where a try/catch block would make sense.
$req['variables']['API_KEY'] this could throw an exception
Indeed, removing this line eliminates the failures. But what is wrong with that code? I am accessing an array that appwrite should be providing to me, correct?
Yes, it should. Is the variable still in your function settings? The function isn't being redeployed is it?
I supplied a file with the variable. Each time I edit the index.php file I re-upload it. That appears to be considered a redeployment. But how would that cause the variables to be passed only half the time and in a cyclical fashion?
Sorry what do you mean?
I assigned the API_KEY variable in a file and uploaded it to the function. I did this just once. Every time I make a change to index.php, I create a deployment on the command line of my Mac, and it shows up as a new active deployment. I then execute the function by clicking the Execute Now button. If the prior execution failed, this one will succeed. Then the next one will fail, ad infinitum. So it appears that appwrite has a memory across function executions, and it passes the API_KEY variable on every other execution only.
You mean you're uploading a .env file?
What command are you running to deploy the function?
I "imported" an .env file. I did that at the initial creation of the function. The command I used to deploy the function is appwrite functions createDeployment --functionId=650d12f2bf31e2ea6fba --entrypoint='index.php' --code="." --activate=true
API_KEY isn't false, right? It's not set at all?
I have it set to the password I use for my appwrite account. It's also the value of the openssl key. All three are the same value.
I mean when it fails, it's not set to false, right?
If you log $req['variables'], it's either an empty array or an array with variables?
All the variables are there. That's not the cause. If I put in this function ```function returnAllTheTanks($api_key) {
//$q = new Query();
//$tankQuery = [ $q->equal("facility_fk",'64bdd24440f7ab4908db'),$q->limit(5000)]; // 64bdd24440f7ab4908db is facility document id (not facility collection)
//return queryDocument('6408223c577dec6908e7', $tankQuery, $api_key); // 6408223c577dec6908e7 is tank collection id
}``` where I have an empty function body because that’s commented out, I get the cyclical failing. If I totally comment out this function, it always runs, so it appears there's something going on with php interpreter inside appwrite that is triggering these failures.
how long do the successes and failures take? I wonder if it actually could be timing out
@grave dawn could this mean one of ur many workers and DBs are flakey?
Oh this is different than what you mentioned before...So what's the full code that's failing now?
Maybe...but probably not 🧐
Whether a given execution fails or succeeds is 100% dependent on what the last execution did.
Last execution failed; the upcoming will succeed
Last executions succeeds; the upcoming will fail
The following code triggers this type of behavior
<?php
require 'vendor/autoload.php';
use Appwrite\Client;
use Appwrite\Services\Databases;
use Appwrite\Query;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
return function ($req, $res) {
function returnAllTheTanks($api_key) {
}
$res->json([
'message' => 'Did I pass!',
]);
}
?>
The mere presence of the empty function
function returnAllTheTanks($api_key) {
}
is a deciding factor. Take it out and the function will always succeed.
Thanks for this. I'll try to reproduce the problem with this
That's bizarre! so curious why this changes anything
apologies for the delay. did you figure out the problem? Have you tried using the new 1.4 syntax?
in 1.4, i initialized a starter function using the CLI and modified it as such:
<?php
require(__DIR__ . '/../vendor/autoload.php');
use Appwrite\Client;
// This is your Appwrite function
// It's executed each time we get a request
return function ($context) {
function returnAllTheTanks($context) {
$context->log('inside returnAllTheTanks!');
}
returnAllTheTanks($context);
// You can log messages to the console
$context->log('Hello, Logs!');
// If something goes wrong, log an error
$context->error('Hello, Errors!');
// The `req` object contains the request data
if ($context->req->method === 'GET') {
// Send a response with the res object helpers
// `res.send()` dispatches a string back to the client
return $context->res->send('Hello, World!');
}
// `res.json()` is a handy helper for sending JSON
return $context->res->json([
'motto' => 'Build like a team of hundreds_',
'learn' => 'https://appwrite.io/docs',
'connect' => 'https://appwrite.io/discord',
'getInspired' => 'https://builtwith.appwrite.io',
]);
};
and it worked fine
Sorry, I am still using 1.3.7. I just run the script twice. Once the users are comfortable with my app, which I just rolled out, I'll plan to upgrade to 1.4.x.
Are you still having problems with the function?
It's actually been working under the cron schedule on 1.3.7.
How'd you solve the problem?
I didn't. It appears under cron, it works. I haven't tested it manually since.
Actually, I just found this post about how you can't declare a function twice 🧐
https://stackoverflow.com/questions/1631535/function-inside-a-function
Maybe that's the problem