n8n-io / n8n

Free and source-available fair-code licensed workflow automation tool. Easily automate tasks across different services.
https://n8n.io
Other
45.49k stars 6.25k forks source link

No testing function found for this credential (non-versioned node) #8188

Open umanamente opened 8 months ago

umanamente commented 8 months ago

Describe the bug

The problem is described here: https://community.n8n.io/t/couldn-t-connect-with-these-settings-no-testing-function-found-for-this-credential/33558/1

Code: https://github.com/NguyeNgocPhus/n8n-test-node

Environment (please complete the following information):

n8n version: 1.17.1 Database: Postgres Running n8n via: desktop app Operating system: Windows

Additional context

There are multiple reports of this problem, and no solution provided yet.

Joffcom commented 8 months ago

Hey @umanamente,

I am going to mark this as closed as this doesn't appear to be an issue with n8n itself and looks to be more related to the code in the node.

Now the code is available and I am back from my time off I will reply back on the forum post once I have had a look, Let me know if you have any other questions about this.

netroy commented 8 months ago

There are multiple reports of this problem.

I only see the issue you linked. Can you please link other issues here as well? 🙏🏽

umanamente commented 8 months ago

There are multiple reports of this problem.

I only see the issue you linked. Can you please link other issues here as well? 🙏🏽

This Stackoverflow question refers to the same problem: https://stackoverflow.com/questions/75109822/n8n-node-development-no-testing-function-found-for-this-credential

I also have this problem with the node I'm developing: https://github.com/umanamente/n8n-nodes-imap

umanamente commented 8 months ago

Hey @umanamente,

I am going to mark this as closed as this doesn't appear to be an issue with n8n itself and looks to be more related to the code in the node.

Now the code is available and I am back from my time off I will reply back on the forum post once I have had a look, Let me know if you have any other questions about this.

@Joffcom, I think that it is most likely a problem with n8n, because I don't see a reason why couldn't n8n find testing function for a credential. I'll wait for your reply to the original post, and please also check the StackOverflow question related the same issue: https://stackoverflow.com/questions/75109822/n8n-node-development-no-testing-function-found-for-this-credential

Joffcom commented 8 months ago

Hey @umanamente,

I had only seen the one report of this and our internal nodes don't seem to have the same issue so based on that information it seemed unlikely to be an issue with n8n.

I will do some digging and see if I can find anything, I now have 2 different repos I can check which is very handy. I remember an issue we had with polling times not showing up for community nodes so it could be something similar here.

biclighter81 commented 8 months ago

We have the same issue. The template repo for custom nodes doesn't include a package.json script to generate known nodes and credentials json files (have a look in the dist folder of the base n8n nodes package for reference).

dist/known/credentials.json (nodes-base)

{
  "actionNetworkApi": {
    "className": "ActionNetworkApi",
    "sourcePath": "dist/credentials/ActionNetworkApi.credentials.js",
    "supportedNodes": [
      "actionNetwork"
    ]
}

After copying the scripts from base n8n nodes package and executing them the json files will be generated. package.json (n8n-nodes-CUSTOM)

"build": "tsc && gulp build:icons && pnpm run build:metadata",
"build:metadata": "pnpm n8n-generate-known && pnpm n8n-generate-ui-types",

But there is an issue. If you build the n8n master branch by yourself or install n8n with the latest version globally (npm i -g n8n) the LoadNodesAndCredentials.ts file tries to find nodes which can use the credential class via the supportedNodes parameter. packages/cli/src/LoadNodesAndCredentials.ts

this.known.credentials[type] = {
    className,
    sourcePath: path.join(directory, sourcePath),
    supportedNodes:
        loader instanceof PackageDirectoryLoader
            ? supportedNodes?.map((nodeName) => `${loader.packageName}.${nodeName}`)
            : undefined,
    extends: extendsArr,
};

But the mentioned n8n-generate-known script from the n8n-core package with the latest releases version on npm (1.14.1) puts the supported nodes in the nodesToTestWith parameter, which then won't get picked up by n8n.

"QueryDB": {
    "className": "QueryDB",
    "sourcePath": "dist/credentials/QueryDB.credentials.js",
    "nodesToTestWith": [
      "QueryDB"
    ]
  }

Lastly I can just give you a fix for development (in production it shouldn't be a problem):

  1. Build the n8n Repo (master branch)
  2. cd packages/core
  3. cd into your custom n8n nodes directory
  4. pnpm link PATH_TO_BUILDED_N8N\packages\core
  5. Build your custom nodes and start n8n (testing function will now get picked up)
Joffcom commented 7 months ago

The internal ticket for this is PAY-1274, I will let you know when we have fixed this.

tonymorello commented 7 months ago

Hey @Joffcom I fixed this issue by changing the code in packages/cli/src/LoadNodesAndCredentials.ts from:

      for (const type in known.credentials) {
        const {
          className,
          sourcePath,
          supportedNodes,
          extends: extendsArr,
        } = known.credentials[type];
        this.known.credentials[type] = {
          className,
          sourcePath: path.join(directory, sourcePath),
          supportedNodes:
            loader instanceof PackageDirectoryLoader
              ? supportedNodes?.map((nodeName) => `${loader.packageName}.${nodeName}`)
              : undefined,
          extends: extendsArr,
        };
      }

to:

      for (const type in known.credentials) {
        const {
          className,
          sourcePath,
          supportedNodes,
          extends: extendsArr,
        } = known.credentials[type];
        this.known.credentials[type] = {
          className,
          sourcePath: path.join(directory, sourcePath),
          supportedNodes:
            loader instanceof PackageDirectoryLoader
              ? Object.keys(loader.nodeTypes).length > 0
        ? Object.keys(loader.nodeTypes)
        : supportedNodes?.map((nodeName) => `${loader.packageName}.${nodeName}`)
              : undefined,
          extends: extendsArr,
        };
      }

Hope it helps.

Joffcom commented 7 months ago

Hey @tonymorello,

Feel free to pop in a PR if you have time and I can add it to the dev ticket for the team to look at.