How to debug custom node during development?

Hi all. I am currently building my first custom node and am a bit stuck with the execution development part. Also, newbie in TS.
Have been trying to refer to the code of other nodes, but that’s not enough.

E.g. built an ApiRequest function in GenericFunctions.ts to dynamically load options in the node. But it doesn’t work at all.

How to go about debugging this?

Usually, i would just console.log the various steps but that doesn’t seem to work in this situation.


Also, my code in the ApiRequest functions keeps giving errors for custom properties, like:

n8n-nodes-base: nodes/Directus/GenericFunctions.ts(37,24): error TS2339: Property 'url' does not exist on type 'Promise<ICredentialDataDecryptedObject | undefined>'.
n8n-nodes-base: nodes/Directus/GenericFunctions.ts(38,32): error TS2339: Property 'accessToken' does not exist on type 'Promise<ICredentialDataDecryptedObject | undefined>'.
n8n-nodes-base: nodes/Directus/GenericFunctions.ts(53,59): error TS2339: Property 'data' does not exist on type 'RequestPromise<any>'.

What to do about this?

Happy to take a look if you can share the code.

Thanks! Sent you a DM.

Regarding the TS errors on L37-38, this.getCredentials() now returns a Promise<T>, so you need to await it before you can use its contents:

const credentials = await this.getCredentials('directusApi');

You can also explicitly cast the return type to the shape of the object coming from the credentials:

const credentials = await this.getCredentials('directusApi') as { url: string; accessToken: string };

This change was introduced this week with #1741. Hopefully the tutorial can be updated soon @harshil1712

Regarding the TS error on L53, you are accessing data on the unawaited result of calling this.helpers.request(). The promise has not resolved by then, so the property access fails. You can await the result and then access it, or preferably return the raw response and let the caller decide what to do with data, since maybe not all endpoints return this property.

return await this.helpers.request!(options);

Regarding load options, with the L53 fix the call should succeed, giving you access to the collections data on the load options side. Let me know otherwise.

@ivov Thanks a lot for the debug info!

I made the appropriate changes.

And these errors have now resolved.

But, the dynamic options are still not loading.
How to debug that?

Check if the load options method call succeeded:

const response = await directusApiRequest.call(this, 'GET', 'collections');
// expected: response.data.collections

Check if its return value is properly shaped:

return returnData;
// expected: [{ name: 'x', value: 'y' }, { name: 'x', value: 'y' }]

Check if the param is type options and points to the load options method:

{
  displayName: 'Your Param Name',
  name: 'yourParamName',
  type: 'options',
  default: '',
  typeOptions: {
    loadOptionsMethod: [
      'yourMethodName',
    ],
  },
  <rest ellided>
}

By ‘check’, do you mean check using the Logger class?
So, Logger.info('Data',{response}) ?

Or, is there also some other way of checking the data?

With console.log the value will show up in the console for the npm run start process:

const response = await directusApiRequest.call(this, 'GET', 'collections');
console.log(response);
console.log(returnData);
return returnData;
1 Like

I’ve come across another issue with my setup.
After multiple changes, my node is now stuck. I can see the options for Resource and Operation but can’t select any of them.

Would appreciate any insight regarding this error:

Error: Could not resolve parameter depenencies. Max itterations got reached!
    at u (NodeHelpers.js:372)
    at c (NodeHelpers.js:402)
    at c (NodeHelpers.js:399)
    at Object.c [as getNodeParameters] (NodeHelpers.js:460)
    at s.valueChanged (NodeSettings.vue:358)
    at rt (vue.runtime.esm.js:1863)
    at s.n (vue.runtime.esm.js:2188)
    at rt (vue.runtime.esm.js:1863)
    at s.Tn.e.$emit (vue.runtime.esm.js:3903)
    at s.valueChanged (ParameterInputList.vue:220)

What to make of this? And where, in my code, could the issue be?

Thanks.

In your params, it is likely the type and default value do not match, e.g. type: string defaulting to a number.

Nodelinter should be able to locate the mismatch:

Otherwise feel free to send your latest code.

3 Likes

Thanks for this link.

Have now managed to bring down 300+ linting errors to 6.
But, can’t seem to resolve the remaining errors, even though everything seems to be configured properly.

Sending you now.

In ItemsDescription.ts remove L381 to L390. displayOptions that are already specified in the parent do not need to be in the child.

Will add this check to the nodelinter and open a PR to improve the max iterations error message.

After doing this and rebuilding, still getting the same error. Particularly, the node gets stuck once the Field resource is selected.

Also, while checking with the nodelinter (npx nodelinter), still getting those 6 errors, including this one:

  ├── 203  ERROR: Param with non-existent `loadOptionsMethod`
  │        The method to load options specified for this param has not
  │        been defined in `methods.loadOptions` in the node.
  │        loadOptionsMethod: 'getCollections'

in FieldsDescription.ts.

Regarding the loadOptionsMethod linting, thank you, it was also reported by another user today. Will disable it soon until fixed - feel free to ignore it.

Regarding the max iterations error, if I run the linter against the version I received today (i.e. in your second PM), I see ~300 lintings instead of 6. Is it possible the code you shared today is not your latest?

For reference, the max iterations fix in my previous message is based on today’s version and I can confirm it works there. Sending you the branch via PM.