Waltari
Waltari

Reputation: 1249

Stuck on console.log(JSON.stringify(req)) in middleware

When I connect to my Express 4 node.js websocket server from my client and try to log req, the whole program just gets stuck. It still accepts new connections and executes it to the same console.log, but then gets stuck. I am trying to figure out what req contains, but this way of figuring it out doesn't seem to work.

app.use(function (req, res, next) {
    console.log("middleware");
    var session = req.session;
    console.log("session: " + JSON.stringify(session));
    console.log("req non json: " + req);
    console.log("req: " + JSON.stringify(req));  //stuck
    return next();
});

Upvotes: 5

Views: 6270

Answers (3)

rcbevans
rcbevans

Reputation: 8882

For anyone hitting this, particularly with serializing Express Request/Response objects, I was able to get this working using a custom stringify function wrapping JSON.stringify which uses the replacer to safely serialize BigInts, Buffers, and circular references.

export const getCircularReplacer = () => {
  const seen = new WeakSet();
  return (key: string, value: unknown) => {
    if (typeof value === 'object' && value !== null) {
      if (seen.has(value)) {
        return '[Circular]';
      }
      seen.add(value);
    }
    return value;
  };
};

export const safeStringify = (value: unknown, space?: string | number) => {
  const circularReplacer = getCircularReplacer();
  return JSON.stringify(
    value,
    (key, value) => {
      if (typeof value === 'bigint') {
        return value.toString();
      } else if (Buffer.isBuffer(value)) {
        return value.toString('base64');
      }

      return circularReplacer(key, value);
    },
    space
  );
};

Upvotes: 1

Adam Genshaft
Adam Genshaft

Reputation: 824

As Gemtastic said the req just can't be stringified. You can use a custom function to stringify your request with all the data you need. Should be something like this:

const reqData = JSON.stringify({
      headers: req.headers,
      method: req.method,
      url: req.url,
      httpVersion: req.httpVersion,
      body: req.body,
      cookies: req.cookies,
      path: req.path,
      protocol: req.protocol,
      query: req.query,
      hostname: req.hostname,
      ip: req.ip,
      originalUrl: req.originalUrl,
      params: req.params,
});

Upvotes: 6

Gemtastic
Gemtastic

Reputation: 6433

What's happening here is that you're trying to stringify req, an object not stringifiable.

console.log() accepts many arguments in the constructor, if you supply one argument and use + what's happening is that you're trying to pass two strings into console.log() stringifying or .toString() the object instead of printing the object's content.

I'm gonna try and explain what you should do and why:

console.log("string as argument one", [object]) This is the desired effect you want, internally console.log() will understand that you want to print the string and the object's content and not the .toString() which most often is [Object object] or doesn't exist (not all objects have a .toString() since they can be created out of different prototypes).

Upvotes: 1

Related Questions