Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assign data in onPreResponse lifecycle extension with takeover #144

Closed
suhanw opened this issue Mar 18, 2020 · 5 comments
Closed

Assign data in onPreResponse lifecycle extension with takeover #144

suhanw opened this issue Mar 18, 2020 · 5 comments
Assignees
Labels
feature New functionality or improvement
Milestone

Comments

@suhanw
Copy link

suhanw commented Mar 18, 2020

Support plan

  • which support plan is this issue covered by? (e.g. Community, Core, Plus, or Enterprise): Community
  • is this issue currently blocking your project? (yes/no): no
  • is this issue affecting a production system? (yes/no): yes

Context

  • node version: 12.14.0
  • module version: [email protected], [email protected]
  • environment (e.g. node, browser, native): node
  • used with (e.g. hapi application, another framework, standalone, ...): hapi application
  • any other relevant information: n/a

How can we help?

Hi! I'm fairly new to yar and hapi, but let me do my best to explain what I'm trying to accomplish:

  • My Hapi server is making calls to another API service, and I use keepAlive agent on these calls, but the challenge we are facing now is every once in a while the service closes the connection and responds with ECONNRESET error.
  • So our 'band-aid' solution for now is to detect these ECONNRESET errors, redirect to homepage, and show a simple alert.
  • What I was hoping to do is to (a) detect the ECONNRESET response on the onPreResponse lifecycle, (b) set an alert message in session, and (c) change the response to a redirect to homepage. Here's the snippet:
server.ext('onPreResponse', function (request, h){
    let response = request.response;

    if (response.message && typeof response.message.includes === 'function' && response.message.includes('ECONNRESET')) {
        request.yar.set('alerts', `Uh-oh. Something went wrong on our end. Please try again.`);
        return h.response().takeover().redirect('/');
    }

    // other code
}
  • Then, I was going to retrieve the alert message from session in one of my homepage route pre-handlers, and save the alert into an app state object that gets sent to the front-end to display the alert.
server.route({
    method: 'GET',
    path: '/',
    config: {
        pre: [
            // other pre-handlers
            { method: getBase, assign: 'basePayload' },
            // other pre-handlers
        ],
        handler: Methods.render
    }
});


const getBase = async (request, h) => {
    let alerts = request.yar.get('alerts');

    // other code
}

But for some reason, the alerts in session did not persist from onPreResponse to the homepage pre-handler, i.e., request.yar.get('alerts') === null in the pre-handler. Is there something about onPreResponse lifecycle that doesn't allow me to save data into session? Any help is greatly appreciated.

Below are my yar options. I tried to distill the code snippets to just the relevant parts, but let me know if I can provide any further info that might help.

{
    plugin: require('yar'),
    options: {
        name: nconf.get('redis:cookieName'),
        maxCookieSize: 0,
        cache: {
            expiresIn: nconf.get('redis:ttl')
        },
        cookieOptions: {
            ttl: nconf.get('redis:ttl'),
            password: nconf.get('redis:secret'),
            isSecure:
                process.env.NODE_ENV === 'production' ||
                process.env.NODE_ENV === 'staging' ||
                process.env.NODE_ENV === 'ephemeral',
            isHttpOnly:
                process.env.NODE_ENV === 'production' ||
                process.env.NODE_ENV === 'staging' ||
                process.env.NODE_ENV === 'ephemeral'
        },
        storeBlank: false
    }
},

Many thanks!

@suhanw suhanw added the support Questions, discussions, and general support label Mar 18, 2020
@hueniverse
Copy link
Contributor

What is happening first, yar registration or your custom onPreResponse ext setup?

@suhanw
Copy link
Author

suhanw commented Mar 19, 2020

They are both plugins included in the same array, but yar appears first in the array:

const plugins = [
    // other plugins
    {
        plugin: require('yar'),
        options: {
            name: nconf.get('redis:cookieName'),
            maxCookieSize: 0,
            cache: {
                expiresIn: nconf.get('redis:ttl')
            },
            cookieOptions: {
                ttl: nconf.get('redis:ttl'),
                password: nconf.get('redis:secret'),
                isSecure:
                    process.env.NODE_ENV === 'production' ||
                    process.env.NODE_ENV === 'staging' ||
                    process.env.NODE_ENV === 'ephemeral',
                isHttpOnly:
                    process.env.NODE_ENV === 'production' ||
                    process.env.NODE_ENV === 'staging' ||
                    process.env.NODE_ENV === 'ephemeral'
            },
            storeBlank: false
        }
    },
    // other plugins
    { plugin: require('./routes/main') },
    // other plugins
];

await server.register(plugins)

require('./routes/main') is the plugin where the onPreResponse ext setup lives.

@hueniverse hueniverse self-assigned this Mar 19, 2020
@hueniverse hueniverse added feature New functionality or improvement and removed support Questions, discussions, and general support labels Mar 19, 2020
@hueniverse hueniverse added this to the 10.0.1 milestone Mar 19, 2020
@hueniverse hueniverse changed the title Can I assign data to session in the onPreResponse lifecycle? Assign data in onPreResponse lifecycle extension Mar 19, 2020
@hueniverse hueniverse changed the title Assign data in onPreResponse lifecycle extension Assign data in onPreResponse lifecycle extension with takeover Mar 19, 2020
@hueniverse
Copy link
Contributor

You need to call the new await request.yar.commit(h) before returning the redirect.

@suhanw
Copy link
Author

suhanw commented Mar 19, 2020

Is this a new feature that's not available in [email protected]?

@hueniverse
Copy link
Contributor

Only in 10.1.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New functionality or improvement
Projects
None yet
Development

No branches or pull requests

2 participants