rollbar.js
rollbar.js copied to clipboard
TypeError when console.log a dynamic Imports
In a React project using ViteJS, console.logging the result of a dynamic import triggers an error in Rollbar.
Example code to replicate the issue:
App.jsx
import Rollbar from 'rollbar';
new Rollbar({
accessToken: 'xxx',
captureUncaught: true,
captureUnhandledRejections: true,
});
const x = await import('./module');
console.log(x); // raise error
const App = () => (
<>
<h1>Hello World</h1>
</>
);
export default App
module.js
export const x = 1;
The error raised is ;
Uncaught TypeError: Cannot convert object to primitive value
at Array.join (<anonymous>)
at Object.formatArgsAsString (utility.js:676:17)
at e2.<computed> [as log] (telemetry.js:520:23)
Based on my understanding the problem stems from the formatArgsAsString and typeName functions.
The function typeName(x) returns 'module'. Due to this, within formatArgsAsString, the code fails to satisfy any condition in the switch statement.
The final line of formatArgsAsString is
return result.join(' ');.
This results in an error because the join method attempts to call toString, which does not exist in this context. Consequently, JavaScript attempts to convert the object to a string and fails, leading to the error message: "Cannot convert object to primitive value."
(in module.js, if we add export const toString = () => 'hello'; the error is not raised.)
Possible correction could be :
function formatArgsAsString(args) {
var i, len, arg;
var result = [];
for (i = 0, len = args.length; i < len; ++i) {
arg = args[i];
var x = typeName(arg);
switch (x) {
case 'object':
arg = stringify(arg);
arg = arg.error || arg.value;
if (arg.length > 500) {
arg = arg.substr(0, 497) + '...';
}
break;
case 'null':
arg = 'null';
break;
case 'undefined':
arg = 'undefined';
break;
case 'symbol':
arg = arg.toString();
break;
case 'module':
if (arg.toString) {
arg = arg.toString();
} else {
arg = JSON.stringify(arg);
}
break;
default:
arg = JSON.stringify(arg) || String(arg);
}
result.push(arg);
}
return result.join(' ');
}
or more generic adding a default :
default:
arg = JSON.stringify(arg) || String(arg);