Back

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

  • 0
  • Functions
Binyamin
16 Jul, 2023, 22:05

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.

TL;DR
The issue raised in the support thread has been solved with a fix available on GitHub. The problem described pertains to an uncaught exception in a function causing synchronous execution to wait until a timeout is reached, resulting in a 500 error response. The use of the 'zone' is for collecting user output, and the response is not being sent back. The thread provides code examples and discusses the cause and potential solutions for the issue.
Binyamin
16 Jul, 2023, 22:11

Also, When you're executing this function what is happening?

obiwanzenobi
16 Jul, 2023, 22:11

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

obiwanzenobi
16 Jul, 2023, 22:12

I see crash stacktrace in runtime container but executor container is waiting till timeout

obiwanzenobi
16 Jul, 2023, 22:19

ok I found it

Binyamin
16 Jul, 2023, 22:19

Okay, So let's summarized,

These two exceptions has nothing to do with your server code

TypeScript
    } 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

TypeScript
      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

TypeScript
(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

TypeScript
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

Binyamin
16 Jul, 2023, 22:19

Which in your case is empty

obiwanzenobi
16 Jul, 2023, 22:19

this could be problem only with dart runtime, I will confirm that in js today

obiwanzenobi
16 Jul, 2023, 22:20

but consider this code

obiwanzenobi
16 Jul, 2023, 22:20
TypeScript
          try {
            await runZonedGuarded(
              () async => throw Error(),
              (error, stack) {
                print('error inside $error');
              },
            );
            print('completed');
          } catch (e) {
            print('error outside $e');
          }
Binyamin
16 Jul, 2023, 22:20

Then you shouldn't see this one

TypeScript
 print('error outside $e');
obiwanzenobi
16 Jul, 2023, 22:20

this prints: error inside Instance of 'Error'

Binyamin
16 Jul, 2023, 22:20

Exactly

obiwanzenobi
16 Jul, 2023, 22:21

so this stuck because of this zone

obiwanzenobi
16 Jul, 2023, 22:21

and response is never send back

Binyamin
16 Jul, 2023, 22:21

And yes it's probably will be only in dart due to the way of the server runtime

Binyamin
16 Jul, 2023, 22:22

The reason they use zone is to be able to collect the output of the user

TypeScript
 print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
  userLogs.add(line);
 },
obiwanzenobi
16 Jul, 2023, 22:23

sure, but in the documentation this is described:

TypeScript
/// 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.
Binyamin
16 Jul, 2023, 22:25

That's why the response is being return after the zone. All the await are inside, and the return is outside.

obiwanzenobi
16 Jul, 2023, 22:49

just confirmed that works as expected on node runtime

obiwanzenobi
16 Jul, 2023, 22:49

Thanks for support, I will create issue in open runtimes repository

Binyamin
16 Jul, 2023, 22:51

<a:agooglethumbsup:635256484682530825>

obiwanzenobi
16 Jul, 2023, 23:01

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

obiwanzenobi
16 Jul, 2023, 23:16
Reply

Reply to this thread by joining our Discord

Reply on Discord

Need support?

Join our Discord

Get community support by joining our Discord server.

Join Discord

Get premium support

Join Appwrite Pro and get email support from our team.

Learn more