Skip to content
This repository has been archived by the owner on Oct 23, 2023. It is now read-only.

How to add user data to the error object in express #160

Closed
elliot-a opened this issue May 17, 2016 · 8 comments
Closed

How to add user data to the error object in express #160

elliot-a opened this issue May 17, 2016 · 8 comments

Comments

@elliot-a
Copy link

I am adding user data to the req object in express as shown in this simplified example below. I am then using the dataCallback function to check to see if the user data has been added and it doesn't look like it has.

var raven = new Raven.Client( config.SENTRY_DSN, {
    dataCallback: function(data) {
        console.log(data.request.user.name); // undefined
        return data;}
});

app.get('/example', addUserData, function (req, res) {
    throw new Error('Broke!');
});

app.use(Raven.middleware.express.errorHandler(raven));

function addUserData(req, res, next){
    req.user = { name:'john', id:'1' }
    next();
}

However none of that user data seems to present on 'data' object that is passed into 'dataCallback' function. It seems more like the raw request before my custom middleware has added stuff to the object.

Am I missing obvious something here, is there another way of passing user data to Sentry in express? Do you have an example anywhere?

Thanks guys!

@benvinegar
Copy link
Contributor

Hi @elliot-a – sorry for the slow reply.

Setting context right now in an express app isn't straight forward. I'm going to look at some solutions this week.

@vineethawal
Copy link
Contributor

Hi @benvinegar, you guys giving any thoughts on this?

@benvinegar
Copy link
Contributor

@elliot-a, @vineethawal – Quick question, is it reasonable to just tell Express users, "just set req.user"? And then have the middleware take that and set the proper user context? If so, I can make that change to the request parser.

@vineethawal
Copy link
Contributor

@benvinegar sounds fine 👍

@chemitaxis
Copy link

Hi! Is this avalaible right now? Thanks!

@kamilogorek
Copy link
Contributor

@chemitaxis yes :)

@surdu
Copy link

surdu commented Feb 28, 2018

This doesn't seem to work.

Looking at the code, I see the req is passed here as the req key inside the kwargs, but when it's extracted from kwargs it's extracted from kwargs.user instead of kwargs.req.user.

Am I missing something ?

@kamilogorek
Copy link
Contributor

kamilogorek commented Feb 28, 2018

@surdu user is extracted from the request later down the road -

raven-node/lib/parsers.js

Lines 129 to 155 in ea19288

// user: typically found on req.user in express/passport patterns
// five cases for parseUser value:
// absent: grab only id, username, email from req.user
// false: capture nothing
// true: capture all keys from req.user
// array: provided whitelisted keys to grab from req.user
// function :: req -> user: custom parsing function
if (parseUser == null) parseUser = ['id', 'username', 'email'];
if (parseUser) {
var user = {};
if (typeof parseUser === 'function') {
user = parseUser(req);
} else if (req.user) {
if (parseUser === true) {
for (var key in req.user) {
if ({}.hasOwnProperty.call(req.user, key)) {
user[key] = req.user[key];
}
}
} else {
parseUser.forEach(function(fieldName) {
if ({}.hasOwnProperty.call(req.user, fieldName)) {
user[fieldName] = req.user[fieldName];
}
});
}
}

I wonder if this is skipped when request object is created correctly here -

raven-node/lib/client.js

Lines 237 to 261 in ea19288

/*
`request` is our specified property name for the http interface: https://docs.sentry.io/clientdev/interfaces/http/
`req` is the conventional name for a request object in node/express/etc
we want to enable someone to pass a `request` property to kwargs according to http interface
but also want to provide convenience for passing a req object and having us parse it out
so we only parse a `req` property if the `request` property is absent/empty (and hence we won't clobber)
parseUser returns a partial kwargs object with a `request` property and possibly a `user` property
*/
kwargs.request = this._createRequestObject(
globalContext.request,
domainContext.request,
kwargs.request
);
if (Object.keys(kwargs.request).length === 0) {
var req = this._createRequestObject(
globalContext.req,
domainContext.req,
kwargs.req
);
if (Object.keys(req).length > 0) {
var parseUser = Object.keys(kwargs.user).length === 0 ? this.parseUser : false;
extend(kwargs, parsers.parseRequest(req, parseUser));
delete kwargs.req;
}
}

Can you provide a non-working example that I could use to reproduce the issue?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants