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

3

5

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();
});
Converter answered 24/7, 2015 at 7:43 Comment(4)
It's probably not stuck but throwing an exception, as you most likely cannot stringify req due to circular references. Try console.log('req:', req).Beanstalk
Thanks that worked, but how is "console.log('req:', req)" different from "console.log("req: " + req);" ??Converter
Using + stringifies req, using it as a separate argument will make console.log() use util.inspect().Beanstalk
@Converter it is string concatenation. The req object is appended to 'string' first.Asterism
U
1

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).

Unmannered answered 24/7, 2015 at 8:46 Comment(0)
C
6

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,
});
Connacht answered 5/2, 2021 at 20:36 Comment(0)
U
1

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).

Unmannered answered 24/7, 2015 at 8:46 Comment(0)
C
0

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
  );
};
Cantonment answered 6/12, 2023 at 22:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.