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

[BUG v5.0.0] TypeError: Cannot convert undefined or null to object on get operation #151

Closed
StefanoSega opened this issue Oct 24, 2019 · 8 comments
Assignees
Labels

Comments

@StefanoSega
Copy link

With the same code that used to work with v4.x.x:

const NodeCache = require('node-cache');

const cacheSsr = new NodeCache({
  stdTTL: 5,
  checkperiod: 0,
});

module.exports = cacheSsr;
export class SsrCache {
  private _cache: any;

  constructor() {
    this._cache = require('./cacheSsr');
  }

  get(key) {
    const cacheSsr = this._cache;

    return cacheSsr.get(key);
  }
}
import { SsrCache } from './ssrHelper';

const ssrCache = new SsrCache();

const cachedData = ssrCache.get('key');

it returns the error

TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at NodeCache._getValLength (webpack:///./node_modules/node-cache/lib/node_cache.js?:690:56)
    at NodeCache.del (webpack:///./node_modules/node-cache/lib/node_cache.js?:461:38)
    at NodeCache._check (webpack:///./node_modules/node-cache/lib/node_cache.js?:600:18)
    at NodeCache.get (webpack:///./node_modules/node-cache/lib/node_cache.js?:332:46)
    at SsrCache.get

mind that for sure in the cache there's no value for that key

@erdii
Copy link
Member

erdii commented Oct 24, 2019

Whoa sorry for that!
I cannot reproduce that :(

Can you elaborate on:

  • node version
  • webpack setup
  • typescript setup

please?

package.json:

{
  "name": "tmp.VHDDkc0A",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "node-cache": "^5.0.0"
  }
}

index.js:

const NodeCache = require('node-cache');

const cacheSsr = new NodeCache({
  stdTTL: 5,
  checkperiod: 0,
});

class SsrCache {
  constructor() {
    this._cache = cacheSsr;
  }

  get(key) {
    const cacheSsr = this._cache;

    return cacheSsr.get(key);
  }
}

const ssrCache = new SsrCache();
const cached = ssrCache.get("key");

@StefanoSega
Copy link
Author

StefanoSega commented Oct 24, 2019

Hi @erdii and thanks for answering.

  • node version is v10.13.0
  • webpack setup:
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const ServerMiniCssExtractPlugin = require("./server/utils/serverMiniCssExtractPlugin");
const LoadablePlugin = require('@loadable/webpack-plugin');

const getCssLoader = (localIdentName, localsConvention) => ({
  loader: 'css-loader',
  options: {
    modules: {
      localIdentName,
    },
    localsConvention,
    sourceMap: true,
  }
});
const sassLoader = 'sass-loader';
const postcssLoader = 'postcss-loader';

module.exports = [{
  name: 'react-app',
  mode: 'development',
  devtool: 'eval',
  cache: true,
  entry: {
    main: [
      'babel-polyfill',
      'webpack-hot-middleware/client?reload=true',
      './react/index.tsx',
    ],
  },
  output: {
    path: `${__dirname}/dist/__build__`,
    filename: '[name].js',
    chunkFilename: '[name].[hash].js',
    publicPath: '/__build__/',
  },
  module: {
    rules: [{
      test: /\.(ts|js)x?$/,
      loader: 'babel-loader',
      exclude: [/node_modules/],
    }, {
      test: /\.scss$/,
      oneOf: [{
        resourceQuery: /^\?raw$/,
        use: [
          MiniCssExtractPlugin.loader,
          getCssLoader('[local]', 'asIs'),
          sassLoader,
          postcssLoader
        ],
      }, {
        use: [
          MiniCssExtractPlugin.loader,
          getCssLoader('[path]___[name]__[local]___[hash:base64:5]', 'camelCaseOnly'),
          sassLoader,
          postcssLoader
        ],
      }]
    }],
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js'],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        CLIENT: JSON.stringify(true),
        ENV: JSON.stringify(process.env.ENV)
      },
    }),
    new webpack.IgnorePlugin(/^vertx$/),
    new MiniCssExtractPlugin({
      filename: "style.css",
      chunkFilename: "style.chunk.css"
    })
  ],
  optimization: {
    splitChunks: {
      cacheGroups: {
        vendor: {
          test: /node_modules/,
          name: 'vendor',
          enforce: true
        },
        style: {
          test: /\.scss$/,
          name: 'style',
          enforce: true
        },
      },
    },
  },
}, {
  name: 'server-side rendering',
  mode: 'development',
  devtool: 'eval',
  cache: true,
  entry: [
    './react/ssr.tsx',
  ],
  target: 'node',
  output: {
    path: `${__dirname}/dist/__server__/`,
    filename: 'ssr.js',
    publicPath: '/__server__/',
    libraryTarget: 'commonjs2',
  },
  resolve: {
    extensions: ['.ts', '.tsx', '.js'],
  },
  module: {
    rules: [{
      test: /\.(ts|js)x?$/,
      exclude: [/node_modules/, /.+\.config.js/],
      loader: 'babel-loader',
    }, {
      test: /\.scss$/,
      oneOf: [{
        resourceQuery: /^\?raw$/,
        use: [
          ServerMiniCssExtractPlugin.loader,
          getCssLoader('[local]', 'asIs'),
          sassLoader,
          postcssLoader
        ],
      }, {
        use: [
          ServerMiniCssExtractPlugin.loader,
          getCssLoader('[path]___[name]__[local]___[hash:base64:5]', 'camelCaseOnly'),
          sassLoader,
          postcssLoader
        ],
      }]
    }],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        SERVER: JSON.stringify(true),
        ENV: JSON.stringify(process.env.ENV)
      },
    }),
    new webpack.IgnorePlugin(/^vertx$/),
    new ServerMiniCssExtractPlugin({
      filename: "style.css",
      chunkFilename: "style.chunk.[id].css"
    }),
    new LoadablePlugin()
  ],
}];
  • typescript setup (tsconfig.json):
{
  "compilerOptions": {
      "outDir": "./dist/__build__/",
      "sourceMap": true,
      "noImplicitAny": true,
      "module": "esnext",
      "target": "es5",
      "types": ["jest", "node"],
      "lib": ["es2015", "es2019", "dom"],
      "jsx": "react",
      "moduleResolution": "node",
      "experimentalDecorators": true,
      "esModuleInterop": true,
      "baseUrl": ".",
      "paths": {
        "*": ["./react/@types/*"]
      }
  },
  "include": [
      "./react/**/*.tsx",
      "./react/**/*.ts",
      "./tests/jestsetup.ts",
      "./tests/react/**/*.tsx"
  ]
}

forgot to tell, the error is happening in the server-side rendering of the application, don't know if I disable the SSR

@erdii
Copy link
Member

erdii commented Oct 24, 2019

hm... I feared, that you would try to use node-cache in the browser, but it's dependency on the internal "events" module should make that impossible.

But you tried on the server-side and node_modules are excluded from webpack in your config... that should work

Can you maybe show me the generated parts of your code?

@jwest23
Copy link

jwest23 commented Oct 30, 2019

I get a similar error when trying to set to null, Node 10.16.3. No webpack, no typescript, node-cache@5.0.0, clone@2.1.2:

$ cat test.js 
'use strict';

const cache = new (require('node-cache'))();

try {
  cache.set('test', null);
} catch (err) {
  console.error(err);
}
$ node test.js 
TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at NodeCache._getValLength (/run/user/1000/test/node_modules/node-cache/lib/node_cache.js:690:56)
    at NodeCache.set (/run/user/1000/test/node_modules/node-cache/lib/node_cache.js:402:34)
    at Object.<anonymous> (/run/user/1000/test/test.js:6:9)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
$ node --version
v10.16.3
$ 

The problem disappears if I change line 688 of lib/node_cache.js from:

} else if (typeof value === "object") {

to:

} else if (value !== null && typeof value === "object") {

@marudor
Copy link

marudor commented Oct 31, 2019

I also have this problem.
It's not longer possible to set null to a key.
Or rather it's possible but throws the error (it still worked)
Once something was set null it will no longer be able to be reset.

Example:

const NodeCache = require('node-cache');
const cache = new NodeCache();

cache.get(1) // undefined
cache.set(1, null) // throws an error
cache.get(1) // now null
cache.set(1, 'this is valid') // also throws an error
cache.get(1) // still null

@erdii
Copy link
Member

erdii commented Oct 31, 2019

Fixed the bug in #152, tests are still running. I'll merge this as soon as they finished and then I'll create a patch release.

Thank you all for debugging and reporting this!

@erdii erdii closed this as completed in 7dcae80 Oct 31, 2019
erdii added a commit that referenced this issue Oct 31, 2019
fixed getValLength for null values; this fixes #151; also added a test
@erdii
Copy link
Member

erdii commented Oct 31, 2019

v5.0.1 has been released! Thank you again and sorry for the inconvenience :)

@jwest23
Copy link

jwest23 commented Oct 31, 2019

Thank you for the quick fix, and for node-cache!

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

No branches or pull requests

4 participants