Budibase / budibase

Low code platform for building business apps and workflows in minutes. Supports PostgreSQL, MySQL, MariaDB, MSSQL, MongoDB, Rest API, Docker, K8s, and more 🚀
https://budibase.com
Other
22.47k stars 1.55k forks source link

Improve error messages when failing to import plugins #9008

Closed antonioleo89 closed 1 year ago

antonioleo89 commented 1 year ago

Hosting

Describe the bug Useless error when trying to install a custom plugin

To Reproduce Steps to reproduce the behavior:

  1. Go to Plugins
  2. Upload a custom plugin
  3. See error

Expected behavior A clear error of the plugin to help the dev to troubleshoot.

Screenshots

image

App Export N/A

Desktop (please complete the following information):

Additional context The BE error on the container is the following:

2022-12-11 17:43:07 Trace: BadRequestError: Failed to import plugin: JS invalid: Cannot read property 'indexOf' of undefined
2022-12-11 17:43:07     at Object.throw (/app/node_modules/koa/lib/context.js:97:11)
2022-12-11 17:43:07     at /app/dist/api/controllers/plugin/index.js:59:22
2022-12-11 17:43:07     at Generator.throw (<anonymous>)
2022-12-11 17:43:07     at rejected (/app/dist/api/controllers/plugin/index.js:6:65)
2022-12-11 17:43:07     at runMicrotasks (<anonymous>)
2022-12-11 17:43:07     at processTicksAndRejections (internal/process/task_queues.js:95:5)
2022-12-11 17:43:07     at /app/dist/api/index.js:74:21
2022-12-11 17:43:07     at Generator.throw (<anonymous>)
2022-12-11 17:43:07     at rejected (/app/dist/api/index.js:6:65)
2022-12-11 17:43:07     at runMicrotasks (<anonymous>)
2022-12-11 17:43:07     at processTicksAndRejections (internal/process/task_queues.js:95:5)`
aptkingston commented 1 year ago

The error is saying your JS code is invalid and providing the error it caught when trying to trying to use your plugin. We're catching an error and giving you back that error message - I don't think that's useless at all.

What "clear error" would you like to see? We could perhaps try to extract the line number (in the minified bundle) but I'm not sure what other information we can get beyond that. The plugin you're uploading has a bug in it, and all we can do is catch that at runtime.

This also isn't a bug, as I'm sure you're well aware.

antonioleo89 commented 1 year ago

Hi @aptkingston thanks for the feedback. The fact is that my JS code is fine. I think is a matter of module installation since I am trying to create a IBM DB2 connector. Without importing the db2 object the installation seems fine.

import { IntegrationBase, SqlQuery } from "@budibase/types"

// @ts-ignore
import ibmdb from "ibm_db2" // this object is breaking the installation

interface Db2Config {
  host: string
  port: number
  user: string
  password: string
  database: string
}

class CustomIntegration implements IntegrationBase {
  private readonly config: Db2Config
  private readonly db: any

  constructor(config: Db2Config) {
    this.config = config
    this.db = ibmdb.open( 'DATABASE=' + this.config.database + 
    ';HOSTNAME=' + this.config.host +
    ';UID=' + this.config.user + 
    ';PWD=' + this.config.password+ 
    ';PORT=' + this.config.port + 
    ';PROTOCOL=TCPIP');
  }

  async create(query: { collection: string, body: string }) {
    return await this.db.create(query.collection, JSON.parse(query.body))
  }

  async read(query: { collection: string }) {
    return await this.db.select(query.collection)
  }
  async update(query: { collection: string, body: string }) {
    return await this.db.update(query.collection, JSON.parse(query.body))
  }

  async change(query: { collection: string, body: string }) {
    return await this.db.change(query.collection, JSON.parse(query.body))
  }

  async modify(query: { collection: string, body: string }) {
    return await this.db.modify(query.collection, JSON.parse(query.body))
  }

  async delete(query: { collection: string }) {
    return await this.db.delete(query.collection)
  }

  async advancedQuery(query: SqlQuery) {
    //return await this.db.query(query.sql)
    return await this.db.then(
      (connection: any) => {
          connection.beginTransaction(function (err: any) {
              connection.query(query.sql).then( (data: any) => {
                return data;
              })
          })        
      }, (err: any) => {
          console.log(err)
      }
    );
  }
}

export default CustomIntegration
aptkingston commented 1 year ago

Hey @antonioleo89. From having a quick look at that package I think I can see why - we unfortunately can't support plugins that depend on binaries. ibm_db2 appears to depend on binaries which are pulled down upon installation, but we're unable to bundle binaries into our JS.

If there was an easy way to detect this then that would be a nice enhancement, so that we could at least provide a useful warning saying that a certain dependency can't be used.

antonioleo89 commented 1 year ago

Hi @aptkingston, thanks for the feedback. If not through plugins, is it possible to create a new datasource using modules needing binaries customising the core? Or I can give up on having Db2 working with budibase?

aptkingston commented 1 year ago

You could certainly use it by forking the repo and adding it as a regular datasource! By doing that you can install whatever packages you need as normal. You could even upstream it as a PR if you felt inclined - we've accepted community contributions for datasources before (ArrangoDB comes to mind).

stale[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity.