hapijs / glue

Server composer for hapi.js
Other
245 stars 62 forks source link

How can I pass a callback function for the plugin i.e "next" in the manifest file? #65

Closed snig-b closed 8 years ago

snig-b commented 8 years ago

This is my manifest.js :

'use strict';

let Database = require('../database/database');
const redis = require('../database/redis');

const database = Database.database;

module.exports = {
    server: {
        debug: {
            request: ['info', 'error'],
            log: ["error"]
        },
        cache: [{
            // Omitted name so that this becomes the default
            // cache client
            engine: "catbox-redis",
            host: "...",
            partition: "def"
        }]
    },
    connections: [
        {
            port: 8003,
            labels: ["..."],
            router: {
                stripTrailingSlash: true
            }
        },
        {
            port: 8004,
            labels: ["..."],
            router: {
                stripTrailingSlash: true
            }
        }
    ],
    registrations: [
        {
            plugin:  {
                register: "./some-module",
                options: {
                    database: database,
                    redis: redis
                }
            },
            options: {
                select: ['...']
            }
        },
       ...
        }
    ]

};

Where can I pass the callback for a plugin??

In the classical method:

server.register(require('myplugin'), (err) => {
    if (err) {
        console.error('Failed to load plugin:', err);
    }
});

I need this callback to execute some code

where can I specify this in manifest??

mtharrison commented 8 years ago

Is this code that you want to execute after all plugins have loaded? If so how about putting it in the Glue.compose callback?

Glue.compose(manifest, options, (err, server) => {

    if (err) {
        throw err;  // an error loading one of the plugins
    }

    // do thing here

    server.start((err) => {

        if (err) {
            throw err;
        }
        console.log('hapi days!');
    });
});

If you want the code to execute as part of the individual plugin loading you can just add it to that plugin's register function.

exports.register = function (server, options, next) {

    // do thing here

    next();
}
snig-b commented 8 years ago

Right... That works. But another problem is that the next() call is breaking for me. When I run the server it says, invalid plug in options register must be a function. And when i remove this method call - next() it executes perfectly. Can you figure out what may be the issue?

mtharrison commented 8 years ago

It's a bit tricky to figure out based on just the code that you've posted. Can you share more? Or if not can you make an example showing the same issue that you can share.

Is ./some-module the only plugin in the manifest? What does it export?

snig-b commented 8 years ago

No.. I have registered multiple plugins. More specifically, I am following the structure shared on https://medium.com/@dstevensio/manifests-plugins-and-schemas-organizing-your-hapi-application-68cf316730ef#.dbxxrz2yz for logical modules as plugins. index.js for these plugins is more or less similar to the one shown here. Only difference being how I have registered them -

registrations: [
        {
            plugin:  {
                register: "./module1",
                options: {
                    database: database,
                    redis: redis
                }
            },
            options: {
                select: ['module1']
            }
        },
        {
            plugin: {
                register: './module2',
                options: {
                    database: database,
                    redis: redis
                }
            },
            options: {
                select: ['module2']
            }
        },
        {
            plugin: {
                register: "./module3",
                options: {
                    database: database,
                    redis: redis
                }
            },
            options: {
                select: ['module3']
            }
        },
        {
            plugin: {
                register: 'good',
                options: {
                // Logging & monitoring.
                reporters: [{
                    reporter: require('good-console'),
                    events: {
                        response: '*',
                        log: '*'
                    }
                }]
            }
            }

        }
    ]

Problem is occurring in my internal plugins only, not the external ones - like 'good'. These plugins' register function export a couple of server routes using 'namespace' utility.

This is my error log:

/home/snigi/Projects/.../node_modules/hapi/node_modules/hoek/lib/index.js:732
    throw new Error(msgs.join(' ') || 'Unknown error');
    ^

Error: Invalid plugin options {
  "options": {
    "database": {},
    "redis": {
      "redis0": {
        "domain": null,
        "_events": {},
        "_eventsCount": 1,
        "options": {
          "port": 6379,
          "host": "localhost",
          "family": 4,
          "connectTimeout": 3000,
          "keepAlive": 0,
          "connectionName": null,
          "sentinels": null,
          "name": null,
          "role": "master",
          "password": null,
          "db": 0,
          "parser": "auto",
          "enableOfflineQueue": true,
          "enableReadyCheck": true,
          "autoResubscribe": true,
          "autoResendUnfulfilledCommands": true,
          "lazyConnect": false,
          "keyPrefix": "",
          "reconnectOnError": null
        },
        "scriptsSet": {},
        "commandQueue": [],
        "offlineQueue": [
          {
            "command": {
              "name": "subscribe",
              "replyEncoding": "utf8",
              "args": [
                "news",
                "music"
              ],
              "transformed": true,
              "promise": {
                "isFulfilled": false,
                "isRejected": false
              }
            },
            "select": 0
          }
        ],
        "connector": {
          "options": {
            "port": 6379,
            "host": "localhost",
            "family": 4,
            "connectTimeout": 3000,
            "keepAlive": 0,
            "connectionName": null,
            "sentinels": null,
            "name": null,
            "role": "master",
            "password": null,
            "db": 0,
            "parser": "auto",
            "enableOfflineQueue": true,
            "enableReadyCheck": true,
            "autoResubscribe": true,
            "autoResendUnfulfilledCommands": true,
            "lazyConnect": false,
            "keyPrefix": "",
            "reconnectOnError": null
          },
          "connecting": true
        },
        "retryAttempts": 0,
        "status": "connecting",
        "condition": {
          "select": 0,
          "auth": null,
          "subscriber": false
        }
      },
      "someconnection": {
        "domain": null,
        "_events": {},
        "_eventsCount": 0,
        "options": {
          "host": "some-ip",
          "port": 6379,
          "db": 1,
          "family": 4,
          "connectTimeout": 3000,
          "keepAlive": 0,
          "connectionName": null,
          "sentinels": null,
          "name": null,
          "role": "master",
          "password": null,
          "parser": "auto",
          "enableOfflineQueue": true,
          "enableReadyCheck": true,
          "autoResubscribe": true,
          "autoResendUnfulfilledCommands": true,
          "lazyConnect": false,
          "keyPrefix": "",
          "reconnectOnError": null
        },
        "scriptsSet": {},
        "commandQueue": [],
        "offlineQueue": [],
        "connector": {
          "options": {
            "host": "some-ip",
            "port": 6379,
            "db": 1,
            "family": 4,
            "connectTimeout": 3000,
            "keepAlive": 0,
            "connectionName": null,
            "sentinels": null,
            "name": null,
            "role": "master",
            "password": null,
            "parser": "auto",
            "enableOfflineQueue": true,
            "enableReadyCheck": true,
            "autoResubscribe": true,
            "autoResendUnfulfilledCommands": true,
            "lazyConnect": false,
            "keyPrefix": "",
            "reconnectOnError": null
          },
          "connecting": true
        },
        "retryAttempts": 0,
        "status": "connecting",
        "condition": {
          "select": 1,
          "auth": null,
          "subscriber": false
        }
      },
      "someconnection2": {
        "domain": null,
        "_events": {},
        "_eventsCount": 0,
        "options": {
          "host": "some-ip",
          "port": 6379,
          "db": 15,
          "family": 4,
          "connectTimeout": 3000,
          "keepAlive": 0,
          "connectionName": null,
          "sentinels": null,
          "name": null,
          "role": "master",
          "password": null,
          "parser": "auto",
          "enableOfflineQueue": true,
          "enableReadyCheck": true,
          "autoResubscribe": true,
          "autoResendUnfulfilledCommands": true,
          "lazyConnect": false,
          "keyPrefix": "",
          "reconnectOnError": null
        },
        "scriptsSet": {},
        "commandQueue": [],
        "offlineQueue": [],
        "connector": {
          "options": {
            "host": "some-ip",
            "port": 6379,
            "db": 15,
            "family": 4,
            "connectTimeout": 3000,
            "keepAlive": 0,
            "connectionName": null,
            "sentinels": null,
            "name": null,
            "role": "master",
            "password": null,
            "parser": "auto",
            "enableOfflineQueue": true,
            "enableReadyCheck": true,
            "autoResubscribe": true,
            "autoResendUnfulfilledCommands": true,
            "lazyConnect": false,
            "keyPrefix": "",
            "reconnectOnError": null
          },
          "connecting": true
        },
        "retryAttempts": 0,
        "status": "connecting",
        "condition": {
          "select": 15,
          "auth": null,
          "subscriber": false
        }
      },
      "pub": {
        "domain": null,
        "_events": {},
        "_eventsCount": 0,
        "options": {
          "port": 6379,
          "host": "localhost",
          "family": 4,
          "connectTimeout": 3000,
          "keepAlive": 0,
          "connectionName": null,
          "sentinels": null,
          "name": null,
          "role": "master",
          "password": null,
          "db": 0,
          "parser": "auto",
          "enableOfflineQueue": true,
          "enableReadyCheck": true,
          "autoResubscribe": true,
          "autoResendUnfulfilledCommands": true,
          "lazyConnect": false,
          "keyPrefix": "",
          "reconnectOnError": null
        },
        "scriptsSet": {},
        "commandQueue": [],
        "offlineQueue": [],
        "connector": {
          "options": {
            "port": 6379,
            "host": "localhost",
            "family": 4,
            "connectTimeout": 3000,
            "keepAlive": 0,
            "connectionName": null,
            "sentinels": null,
            "name": null,
            "role": "master",
            "password": null,
            "db": 0,
            "parser": "auto",
            "enableOfflineQueue": true,
            "enableReadyCheck": true,
            "autoResubscribe": true,
            "autoResendUnfulfilledCommands": true,
            "lazyConnect": false,
            "keyPrefix": "",
            "reconnectOnError": null
          },
          "connecting": true
        },
        "retryAttempts": 0,
        "status": "connecting",
        "condition": {
          "select": 0,
          "auth": null,
          "subscriber": false
        }
      }
    }
  },
  "register" [1]: {}
}

[1] "register" must be a Function
    at Object.exports.contain.exports.reachTemplate.exports.assert.condition [as assert] (/home/snigi/Projects/.../node_modules/hapi/node_modules/hoek/lib/index.js:732:11)
    at Object.exports.apply (/home/snigi/Projects/.../node_modules/hapi/lib/schema.js:17:10)
    at module.exports.internals.Plugin.internals.Plugin.register.each [as register] (/home/snigi/Projects/.../node_modules/hapi/lib/plugin.js:226:25)
    at /home/snigi/Projects/.../node_modules/glue/lib/index.js:119:24
    at iterate (/home/snigi/Projects/.../node_modules/glue/node_modules/items/lib/index.js:36:13)
    at done (/home/snigi/Projects/.../node_modules/glue/node_modules/items/lib/index.js:28:25)
    at /home/snigi/Projects/.../node_modules/hapi/lib/plugin.js:326:16
    at done (/home/snigi/Projects/.../node_modules/hapi/node_modules/items/lib/index.js:31:25)
    at Object.exports.register (/home/snigi/Projects/.../src/modules/module2/index.js:34:5)
    at Object.target [as register] (/home/snigi/Projects/.../node_modules/hapi/node_modules/joi/lib/object.js:80:30)
    at each (/home/snigi/Projects/.../node_modules/hapi/lib/plugin.js:320:14)
    at iterate (/home/snigi/Projects/.../node_modules/hapi/node_modules/items/lib/index.js:36:13)
    at Object.exports.serial (/home/snigi/Projects/.../node_modules/hapi/node_modules/items/lib/index.js:39:9)
    at module.exports.internals.Plugin.internals.Plugin.register.each [as register] (/home/snigi/Projects/.../node_modules/hapi/lib/plugin.js:323:11)
    at /home/snigi/Projects/.../node_modules/glue/lib/index.js:119:24
    at iterate (/home/snigi/Projects/.../node_modules/glue/node_modules/items/lib/index.js:36:13)

Apologies for such a long post.

snig-b commented 8 years ago

I figured out the problem, the index.js of one of the plugins was missing the register function by mistake. The bug here is irrelevant, however the error traceback was nowhere leading me to the issue. The error was being thrown from an altogether different plugin. Anyways, thank you so much for the help, you can please close this issue.

lock[bot] commented 4 years ago

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.