here’s another one I’m running in to. This looks ...
# general
s
here’s another one I’m running in to. This looks like it happens after compilation:
Copy code
error: Error serializing '(ev, ctx, cb) => { let body; ...': api.js(189,21)

    '(ev, ctx, cb) => { let body; ...': api.js(189,21): captured
      variable 'handlers' which indirectly referenced
        function '<anonymous>': organizations.ts(5,14): which could not be serialized because
          arrow function captured 'this'. Assign 'this' to another name outside function and capture that.

    Function code:
      (req, res) => tslib_1.__awaiter(this, void 0, void 0, function* () {
          try {
              const results = yield organization_1.getOrganizations();
              res.status(200).json({
                  results: results
Looking at the compiled JS, it looks like TS is doing this:
Copy code
exports.all = (req, res) => tslib_1.__awaiter(this, void 0, void 0, function* () {
And Pulumi isn’t liking the
this
that it adds in there.
w
Can you share any of your code related to this? There is a limitation that you cannot capture
this
in a serialized function currently, but I’m curious what this case is where TS is generating something that triggers this.
s
sure just a sec
yeh I’m def. not using
this
here…TS is generating it.
been looking aorund to see how i could control that
ts
file:
Copy code
import { getOrganizations } from '../data/models/organization'

export let all = async (req: any, res: any) => {
	try {
		const results = await getOrganizations();

		res.status(200).json({
			results: results
		});
	} catch (e) {
		res.status(400).json({ e });
	}
};
And the compiled version of it:
Copy code
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const organization_1 = require("../data/models/organization");
exports.all = (req, res) => tslib_1.__awaiter(this, void 0, void 0, function* () {
    try {
        const results = yield organization_1.getOrganizations();
        res.status(200).json({
            results: results
        });
    }
    catch (e) {
        res.status(400).json({ e });
    }
});
ive tweaked that code a little to see if its the way its declared…that is just my latest iteration of it to see what TS does. It seems to be related to the
await/asyc
keywords and the tslib
awaiter
helper that is used
yeh just tried it with a few other samples. using async functions will use that tslib helper
__awaiter
which drops
this
in as a param…which causes pulumi to choke while serializing the function
hah. the comments basically spell out exactly what is happening
If I do something weird like restructure it in to a class or it’s own object literal, then it works because
this
isn’t in the module’s scope.
so here’s the weird behavior I hve to do to get this to work:
Copy code
export class OrganizationEndpoint {
	async all(req: any, res: any) {
		import('../data/models/organization');
		try {
			const model = new OrganizationModel();
			const results = await model.all();

			res.status(200).json({
				results: results
			});
		} catch (e) {
			res.status(400).json({ e });
		}
	};
}
which wraps
all
so that “this” is not in the module scope. Then I still have to use that weird
import
inside the method so it will work too.
this works. but super clunky. also it doesn’t work outside of Pulumi without some hacky behavior too.
actually i spoke too soon. it still fails…just takes longer.
starts choking on code lower level now that’s not in my code
Copy code
error: Error serializing '(ev, ctx, cb) => { let body; ...': api.js(189,21)

    '(ev, ctx, cb) => { let body; ...': api.js(189,21): captured
      variable 'handlers' which indirectly referenced
        function 'all': organizations.ts(6,7): which captured
          module './packages/api/data/models/organization.ts' which indirectly referenced
            function 'OrganizationModel': organization.ts(7,15): which captured
              module './packages/api/data/connection.ts' which indirectly referenced
                function '<anonymous>': domain.js(431,38): which captured
                  'ERR_UNHANDLED_ERROR', a function defined at
                    function 'NodeError': errors.js(158,15): which referenced
                      function 'getMessage': errors.js(213,19): which captured
                        variable 'messages' which indirectly referenced
                          function 'get': which could not be serialized because
                            it was a native code function.

    Function code:
      function get() { [native code] }
c
did you try to rewrite your first version(without a class) to a normal function instead of an arrow one? As far as I remember, that worked for me
s
@cold-coat-35200 yeh there are a few different ways I can rewrite it and it will work. it just forces you to do semi-unnatural things, unfortunately.
also. re-writing to not use async/await works too. but that’s unfortunate as well
c
you can still use async/await, I just said to try with normal function instead of arrow
s
yeh if its wrapped so that
this
isn’t inside the module scope
after reading up on this, I think the only way to fix this for pulumi is re-consider how the functions are being serialized OR…some kind of post typescript compilation hook that wraps the
__awaiter
helper so that
this
doesn’t screw things up
Mind you…this is from my limited exposure to this project…so…there’s that 😉
w
Sorry for not jumping in on this sooner - definitely want to better understand what’s going on here - will need to try to create a repro of this. If you have enough details for an isolated repro, feel free to open an issue. Else I’ll look into it soon. Cc also @lemon-spoon-91807 who is the expert here but is out on holiday right now.
s
Ill make a note to create a stand alone example and send you the github link