#[SOLVED] Uncatched exception in a function forces sync execution to wait till timeout to receive 500
79 messages · Page 1 of 1 (latest)
The client should get the error notice right away
Can you screenshot your execution logs from the console?
107ms
The first problem could happened from a few reasons
The most common one is due to mismatch URL,
Can you share your code where is the init of the client?
here is client response (exactly 3min like timeout)
{"$id":"64b455c3ea47a3709ac0","$createdAt":"2023-07-16T20:40:35.959+00:00","$updatedAt":"2023-07-16T20:43:38.798+00:00","$permissions":["read(\"user:64b43cc82bba78b92580\")"],"functionId":"create_update_category","trigger":"http","status":"failed","statusCode":500,"response":"","stdout":"","stderr":"","duration":2.838651}
I think that client is setup properly because there are no problems with other function
hmm which url mismatch you mean?
Okay, make sense
So here you get duration of 2.836
This is seconds not minutes
It means that the client points to unavailable URL
Are you init the client with a URL inside an environment variable?
Have you set that variable for that function?
maybe this is a problem im passing
https://localhost/v1
even if this is on my local machine?
also I have default envs for functions like:
_APP_EXECUTOR_HOST=http://appwrite-executor/v1
_APP_EXECUTOR_RUNTIME_NETWORK=appwrite_runtimes
That's okay for those values
Yes,
In your local environment use your DCHP/router IP
Run to get it
ifconfig # linux / mac
ipconfig # windows
this isnt it, also I changed function logic to not use server side sdk
Future<void> start(final req, final res) async {
throw Exception('Not implemented');
res.json({
'ping': true,
});
}
still have to wait for
final response = await functions.createExecution(
functionId: 'create_update_category',
xasync: false,
);
``` to finish
2023-07-16 23:07:19 [Error] Type: Exception
2023-07-16 23:07:19 [Error] Message: Runtime not found. Please create the runtime.
2023-07-16 23:07:19 [Error] File: /usr/src/code/app/executor.php
2023-07-16 23:07:19 [Error] Line: 469
2023-07-16 23:09:02 [Error] Type: Exception
2023-07-16 23:09:02 [Error] Message: An internal curl error has occurred within the executor! Error Msg: Operation timed out
2023-07-16 23:09:02 [Error] File: /usr/src/code/app/executor.php
2023-07-16 23:06:34 Building container : zday_local-64b45bda2d1711702743
2023-07-16 23:06:43 Executing Runtime: zday_local-64b43cf09e96a97c9b3a
2023-07-16 23:06:49 Build Stage completed in 15 seconds
2023-07-16 23:06:49 Building container : zday_local-64b45bda34008f1235a5
2023-07-16 23:07:07 Build Stage completed in 18 seconds
2023-07-16 23:07:19 Building container : zday_local-64b45bda34008f1235a5
2023-07-16 23:07:20 Build Stage completed in 1 seconds
2023-07-16 23:07:20 Executing Runtime: zday_local-64b45bda34008f1235a5
2023-07-16 23:07:24 Executing Runtime: zday_local-64b45bda34008f1235a5
2023-07-16 23:09:02 [Error] Line: 544
2023-07-16 23:09:43 [Error] Type: Exception
2023-07-16 23:09:43 [Error] Message: An internal curl error has occurred within the executor! Error Msg: Operation timed out
2023-07-16 23:09:43 [Error] File: /usr/src/code/app/executor.php
2023-07-16 23:09:43 [Error] Line: 544
2023-07-16 23:10:20 [Error] Type: Exception
2023-07-16 23:10:20 [Error] Message: An internal curl error has occurred within the executor! Error Msg: Operation timed out
2023-07-16 23:10:20 [Error] File: /usr/src/code/app/executor.php
2023-07-16 23:10:20 [Error] Line: 544
2023-07-16 23:10:24 [Error] Type: Exception
2023-07-16 23:10:24 [Error] Message: An internal curl error has occurred within the executor! Error Msg: Operation timed out
2023-07-16 23:10:24 [Error] File: /usr/src/code/app/executor.php
2023-07-16 23:10:24 [Error] Line: 544
Why you have this line?
throw Exception('Not implemented');
Yes, it seems like something else
just want to fail fast and get faster result
this of course works, but still trying to find why we have to wait to receive the crash
What is your client code?
just this
final response = await functions.createExecution(
functionId: 'create_update_category',
xasync: false,
);
I mean inside the function in the Server side
Future<void> start(final req, final res) async {
throw Exception('Not implemented');
}
This is your function code?
yes, As I Said, I'm trying to understand functions execution
Okay, sorry for my misunderstood
Any Appwrite function must response
So in your case the functions only throws an error which will never be consider as executed.
So you'll need to do something like this
Future<void> start(final req, final res) async {
res.json({
'ping': true,
});
}
And you can response with different answer but you must use
res.json
or
res.send
ok, so no other option than try catch here
Yes
Future<void> start(final req, final res) async {
try {
throw Exception('Not implemented');
res.json({
'success': false,
});
} catch (e) {
res.json({
'success': false,
});
}
}
still weird because execution here should be immediate
https://github.com/appwrite/appwrite/blob/master/app/executor.php#L524
here is code that handles it in runtimes
https://github.com/open-runtimes/open-runtimes/blob/main/runtimes/dart-2.17/server.dart#L39
You can see here that the runtime container will responde only after getting officail resonse from the function
That means the line here
#1130230242712244325 message
will wait until the response is returned (or the timeout has passed)
So when you are executing your function with any res within it, it will never end, and as of that the curl will wait for ever (till the timeout)
Is this make any sense?
but the code in open runtimes that handles this request looks like responds riht after crash
https://github.com/open-runtimes/open-runtimes/blob/main/runtimes/dart-2.17/server.dart#L53
I totally understood that
Yes,
But, You have two types of response.
line with response.body should throw, and this exception should be catched and
} on FormatException catch (_) {
return shelf.Response(500, body: jsonEncode({
'stderr': 'Unable to properly load request body',
'stdout': userLogs.join('\n')
}), headers: headers);
} catch (e) {
return shelf.Response(500, body: jsonEncode({
'stderr': e.toString(),
'stdout': userLogs.join('\n'),
}), headers: headers);
}
As your code runs inside a zone
so this should return instant reponse into executor curl
These exceptions that get caught are in an higher level.
For example the first one is just for bad json,
And you can try to send bad json to the function to see this error.
Also,
When you're executing this function what is happening?
what do you mean by higher level? After completing runZoneGuarded (finishes also after throw) response.body gettter should throw and error should be catched by the last catch braces
I see crash stacktrace in runtime container
but executor container is waiting till timeout
ok I found it
Okay,
So let's summarized,
These two exceptions has nothing to do with your server code
} on FormatException catch (_) {
return shelf.Response(500, body: jsonEncode({
'stderr': 'Unable to properly load request body',
'stdout': userLogs.join('\n')
}), headers: headers);
} catch (e) {
return shelf.Response(500, body: jsonEncode({
'stderr': e.toString(),
'stdout': userLogs.join('\n'),
}), headers: headers);
}
They can be run only if the errro is before your code.
Your code is being executed inside a zone
await runZonedGuarded(
() async {
await user_code.start(request, response);
},
(e, stackTrace) => print('$e $stackTrace'),
zoneSpecification: ZoneSpecification(
print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
userLogs.add(line);
},
),
);
So all of the exceptions made inside the function will be caught by the zone. and then they will be printed out
(e, stackTrace) => print('$e $stackTrace'),
While your output will be added to userLogs object.
Then, after your function as complete - in your case due to exception, then these lines will run
return shelf.Response.ok(
jsonEncode({
"response": response.body,
"stdout": userLogs.join('\n'),
"stderr": ""
}),
headers: headers);
So you can see that the shelf.Response.ok is sending the the response body
Which in your case is empty
this could be problem only with dart runtime, I will confirm that in js today
but consider this code
try {
await runZonedGuarded(
() async => throw Error(),
(error, stack) {
print('error inside $error');
},
);
print('completed');
} catch (e) {
print('error outside $e');
}
Then you shouldn't see this one
print('error outside $e');
this prints:
error inside Instance of 'Error'
Exactly
And yes it's probably will be only in dart due to the way of the server runtime
The reason they use zone is to be able to collect the output of the user
print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
userLogs.add(line);
},
sure, but in the documentation this is described:
/// The zone will always be an error-zone ([Zone.errorZone]), so returning
/// a future created inside the zone, and waiting for it outside of the zone,
/// will risk the future not being seen to complete.
That's why the response is being return after the zone.
All the await are inside, and the return is outside.
just confirmed that works as expected on node runtime
Thanks for support, I will create issue in open runtimes repository

[SOLVED] Uncatched exception in a function forces sync execution to wait till timeout to receive 500