ReferenceError: Cannot access 'web3' before initialization - node.js

chrome-browser-output
chrome-console
After installing the create-react-app package and then creating the web3.js file and adding the console.log(web3.version) to the App.js file im getting the above error and im not sure how to fix it and to get it working.
Ive also tried the following and it still throws the same error.
window.addEventListener('load', async () => {
// Modern dapp browsers...
if (window.ethereum) {
window.web3 = new Web3(ethereum);
try {
// Request account access if needed
await ethereum.enable();
// Acccounts now exposed
web3.eth.sendTransaction({/* ... */});
} catch (error) {
// User denied account access...
}
}
// Legacy dapp browsers...
else if (window.web3) {
window.web3 = new Web3(web3.currentProvider);
// Acccounts always exposed
web3.eth.sendTransaction({/* ... */});
}
// Non-dapp browsers...
else {
console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');
}
});

Error can happen if you haven't called window.ethereum.enable(); yet.

Related

#azure/msal-browser TypeError: this.startPerformanceMeasurement is not a function

Introduction
Because there is no build in Auth library for nuxt 3 yet, I am trying to create my own composable called useAuth.
The Problem
I am getting a startPerformanceMeasurement error when i try to call the loginRedirect or loginPopup method.
Uncaught (in promise) TypeError: this.startPerformanceMeasurement is not a function
at PerformanceClient2.startMeasurement (PerformanceClient.ts:100:45)
at BrowserPerformanceClient2.startMeasurement (BrowserPerformanceClient.ts:46:55)
at RedirectClient2.<anonymous> (StandardInteractionClient.ts:204:64)
at step (_tslib.js:87:23)
at Object.next (_tslib.js:68:53)
at _tslib.js:61:71
at new Promise (<anonymous>)
at __awaiter (_tslib.js:57:12)
at StandardInteractionClient2.getDiscoveredAuthority (StandardInteractionClient.ts:202:115)
at RedirectClient2.<anonymous> (StandardInteractionClient.ts:142:48)
Code
composables/useAuth.js
import * as msal from '#azure/msal-browser'
let state = {
authService: null,
}
export const useAuth = () => {
// use public configuration from nuxt
var config = useAppConfig();
//create authentication instance
state.authService = new msal.PublicClientApplication(config.msalConfig);
//return signIn method
return {
signIn
}
}
const signIn = async () => {
const tokenRequest = {
scopes: [
'openid',
'offline_access',
'Users.Read'
],
}
const response = await state.authService
.loginRedirect(tokenRequest)
.then(() => {
})
.catch(err => {
console.log(err) //TypeError: this.startPerformanceMeasurement is not a function
});
}
Index.vue
<script setup>
if(process.client) {
const auth = useAuth()
auth.signIn()
}
</script>
Apparently this is a bug in the MSAL library.
As mentioned in this issue on Github, they're currently working on a fix.
As a temporary solution, you could downgrade to a previous version. Downgrading might be as simple as just removing the caret character (^) when referring to the version in your package.json.
Edit: They've released a fix as part of msal-common v9.1.1.
I tested by downgrading multiple releases and the first one working was #azure/msal-browser#2.31.0
Faced this issue too. It is caused due to a bug from Microsoft. The versions that work fine are:
"#azure/msal-browser": "2.32.0",
"#azure/msal-common": "9.0.1",
"#azure/msal-react": "1.5.0",
Please ensure to remove the ^ in the number to keep it pinned.
Watch https://github.com/AzureAD/microsoft-authentication-library-for-js/issues/5569 for updates from MS.

Renderer process out of memory after app is packaged into EXE

Expected Behavior
In my main renderer window I'm initializing UI from an imported module. When running the app in dev mode everything works but once I package the app into EXE and try to run it, I'm getting renderer process out of memory error.
The expected behavior is that the packaged app should run like the dev mode.
Actual Behavior
I've checked the electron logs and memory consumption in windows task manager. The memory usage keeps increasing until the renderer process crashes and electron logs oom error.
Since I'm new to electron I've read the documentation but unable to figure out why the same thing is running perfectly in dev mode and crashes in prod.
Log : Renderer process oom - see https://www.electronjs.org/docs/tutorial/application-debugging for potential debugging information.
Another log after some time : [19156:0921/120104.184:ERROR:gpu_init.cc(440)] Passthrough is not supported, GL is swiftshader
So this is what I'm trying to do -
Import my module which is served on localhost:
This module exposes an object - Tesseract through which I initialize my UI.
In the component which is rendered in my main browser window I initialize the UI like this:
File - index.tsx
useEffect(() => {
if (tsToken) {
Tesseract.ui
.init(tsToken.tsToken, "random_id")
.then((sdk: any) => {
console.log("🚀 ~ file: index.js ~ line 3 ~ sdk", sdk);
// After this line nothing is logged and renderer process crashes (But works when I run electron in dev mode)
sdk.init({
...MasterConfig,
RootElement: document.getElementById("tesseract-root"),
});
const authToken = sessionStorage.getItem("ts_token");
ipcRenderer.send("set-globals", { TAC: authToken });
})
.catch((err: any) => console.error(err));
}
}, [tsToken]);
return <></>;
In the above piece of code we pass a root element to the init method. The init method then initializes a react app in that root element.
EDIT:
This is the init method in that module
SDK.prototype.init = async function (config) {
try {
const parsedConfig = JSON.parse(this.META.uiConfig);
window.Tesseract.ui["MasterConfig"] = merge(parsedConfig, config);
window.Tesseract.ui["info"] = this.META;
const projectType = window.Tesseract.ui.MasterConfig.ProjectConfig.type;
console.log("🚀 ~ file: lib.js ~ line 51 ~ projectType", projectType)
const MasterConfig = window.Tesseract.ui["MasterConfig"];
console.log(MasterConfig);
if (
MasterConfig &&
MasterConfig.UserProperties &&
MasterConfig.UserProperties.userId
) {
console.log("React init here");
// Console logs upto this point and then everything fails
// No error logged
try {
RecorderUI.ReactApp({ ...parsedConfig, ...config }).then((obj) => {
// This is never logged
console.log("UI rendered");
return obj;
}).catch(err => console.log(err));
} catch (err) {
console.log(err);
return err;
}
} else {
const e = new Error("User Id Missing");
e.name = "Missing unique user Id";
throw e;
}
} catch (err) {
console.error(err);
return err;
}
};
This is the UI rendering method:
export default async function entry(config) {
// This is never logged so basically something is happening before this
console.log("somemmthing something");
console.log("Root Element: ",
window.Tesseract?.ui?.MasterConfig?.RootElement);
try {
const { RootElement } = config;
RootElement.attachShadow({ mode: "open" });
await IDBStore.create({
version: 1,
name: "ext",
schema: {
globals: "&key",
},
});
const shadowRoot = RootElement.shadowRoot;
const styleElement = document.createElement("style");
styleElement.innerHTML = `${LoaderCss} ${SourcePreviewCSS} ${NotificationCss} ${LibraryCss} ${SelectModeCss} ${WebcamBoxCss} ${CameraBubbleCss} ${countdownCss} ${indexStyles} ${commonCss} ${colorsCss} ${homeCss} ${recordCss} ${advancedOptionsCss} ${recordingTypesCss} ${toggleOptionsCss} ${tourOverlayCss} ${headerCss} ${checkboxCss} ${tooltipCss} ${dropdownCss} ${toggleCss} ${recordButtonCss} ${bannersCss} ${toolsCss} ${canvasCss} ${paintCss} ${recordingControlsCss} ${controlsMainCss}`;
const reactRoot = document.createElement("div");
reactRoot.setAttribute("id", "react-root");
shadowRoot.appendChild(styleElement);
shadowRoot.appendChild(reactRoot);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
reactRoot
);
window.addEventListener("message", handleMessaging, false);
} catch (err) {
console.error(err);
return new Error(err);
}
}
I've read numerous blog posts, github issues but unable to find what's causing this. I need help in determining what is the difference in internal workings of electron which causes such difference b/w running in dev mode vs. packaging the app.

Firebase Cloud Functions with TypeScript: Realtime Database update ends with success but not updates anything, JS works fine

I added Cloud Functions to Firebase project with Firebase CLI. I have started with JavaScript, managed to write working code.
Then I decided to switch to TypeScript. So I decided to delete all Cloud Functions JS related files and start with firebase init cmd from scratch. I copied code from index.js to index.ts, needed only to change how dataMap Map was declared.
So, now whenever I look into console logs on Firebase, everything seems to work fine, everything is logged out, and I'm getting success message on client side.
However nothing happens in Realtime Database, no update, no trace of any data.
I know almost nothing about JS / TS, so every suggestion about code and solution is welcomed.
I'm using node: 14.17.6 and updated firebase-tools to 9.18.0, firebase-admin to 9.11.1 and firebase-functions to 3.15.6.
import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
admin.initializeApp();
exports.createItemWithVIP = functions.region("europe-west1").
https.onCall((data, context) => {
// Checking that the user is authenticated.
if (!context.auth) {
console.log("Unauthenticated request");
throw new functions.https.HttpsError("permission-denied", "You have" +
" no permission to perform this operation");
}
// item details
const foo = data.foo;
const bar = data.bar;
console.log(`foo: ${foo}, bar: ${bar}`);
const userUID = context.auth.uid;
console.log(`userUID: ${userUID}`);
const db = admin.database();
// get new item uid
const somePathTableReference = db.ref("somePath/").push();
const itemUID = `${somePathTableReference}`
.split("somePath/")[1];
console.log(`itemUID: ${itemUID}`);
const itemPath = `somePath/${itemUID}`;
const userPath = `users/${userUID}/somePath/${itemUID}`;
const dataMap = new Map<string, unknown>();
dataMap.set(`${itemPath}/vip/${userUID}`, true);
dataMap.set(`${itemPath}/foo`, foo);
dataMap.set(`${itemPath}/bar`, bar);
dataMap.set(`${userPath}/role`, "vip");
dataMap.set(`${userPath}/foo`, foo);
dataMap.set(`${userPath}bar`, bar);
dataMap.forEach((value: unknown, key: string) =>
console.log(key, value));
return db.ref("/").update(dataMap).then(() => {
console.log(`Added new item with key: ${itemUID} ` +
`; added vip role to user ${userUID}`);
return {"message": "Success"};
}).catch((e) => {
console.log(`Error: ${e}`);
throw new functions.https.HttpsError("unknown", "Unknown error" +
"occured");
});
});
I'm not totally sure about the reason but updating with an object directly instead of new Map() seems to be working (and yes, it didn't work for me with a Map):
const dMap = {
[`${itemPath}/vip/${userUID}`]: true,
[`${itemPath}/foo`]: foo,
[`${itemPath}/bar`]: bar,
[`${userPath}/role`]: "vip",
[`${userPath}/foo`]: foo,
[`${userPath}bar`]: bar
}
try {
await db.ref("/").update(dMap);
console.log(`Added new item with key: ${itemUID}; added vip role to user ${userUID}`);
return {"message": "Success"};
} catch (e) {
console.log(`Error: ${e}`);
throw new functions.https.HttpsError("unknown", "Unknown error" +
"occured");
}
This works for me.
const dMap: { [key: string]: any; } = {};
dMap[`${itemPath}/vip/${userUID}`]= true;
dMap[`${itemPath}/foo`]= foo;
dMap[`${itemPath}/bar`]= bar;
dMap[`${userPath}/role`]= "vip";
dMap[`${userPath}/foo`]= foo;
dMap[`${userPath}bar`]= bar;
db.ref().update(dMap);

Is there a jest config that will fail tests on console.warn?

How do I configure jest tests to fail on warnings?
console.warn('stuff');
// fail test
You can use this simple override :
let error = console.error
console.error = function (message) {
error.apply(console, arguments) // keep default behaviour
throw (message instanceof Error ? message : new Error(message))
}
You can make it available across all tests using Jest setupFiles.
In package.json :
"jest": {
"setupFiles": [
"./tests/jest.overrides.js"
]
}
Then put the snippet into jest.overrides.js
For those using create-react-app, not wanting to run npm run eject, you can add the following code to ./src/setupTests.js:
global.console.warn = (message) => {
throw message
}
global.console.error = (message) => {
throw message
}
Now, jest will fail when messages are passed to console.warn or console.error.
create-react-app Docs - Initializing Test Environment
I implemented this recently using jest.spyOn introduced in v19.0.0 to mock the warn method of console (which is accesses via the global context / object).
Can then expect that the mocked warn was not called, as shown below.
describe('A function that does something', () => {
it('Should not trigger a warning', () => {
var warn = jest.spyOn(global.console, 'warn');
// Do something that may trigger warning via `console.warn`
doSomething();
// ... i.e.
console.warn('stuff');
// Check that warn was not called (fail on warning)
expect(warn).not.toHaveBeenCalled();
// Cleanup
warn.mockReset();
warn.mockRestore();
});
});
There is a useful npm package that helps you to achieve that: jest-fail-on-console
It's easily configurable.
Install:
npm i -D jest-fail-on-console
Configure:
In a file used in the setupFilesAfterEnv option of Jest, add this code:
import failOnConsole from 'jest-fail-on-console'
failOnConsole()
// or with options:
failOnConsole({ shouldFailOnWarn: false })
I decided to post a full example based on user1823021 answer
describe('#perform', () => {
var api
// the global.fetch is set to jest.fn() object globally
global.fetch = jest.fn()
var warn = jest.spyOn(global.console, 'warn');
beforeEach(function() {
// before every test, all mocks need to be resetted
api = new Api()
global.fetch.mockReset()
warn.mockReset()
});
it('triggers an console.warn if fetch fails', function() {
// In this test fetch mock throws an error
global.fetch.mockImplementationOnce(() => {
throw 'error triggered'
})
// I run the test
api.perform()
// I verify that the warn spy has been triggered
expect(warn).toHaveBeenCalledTimes(1);
expect(warn).toBeCalledWith("api call failed with error: ", "error triggered")
});
it('calls fetch function', function() {
// I create 2 more mock objects to verify the fetch parameters
const url = jest.fn()
const config = jest.fn()
api.url = url
api.config = config
// I run the test
api.perform()
// I verify that fetch has been called with url and config mocks
expect(global.fetch).toHaveBeenCalledTimes(1)
expect(global.fetch).toBeCalledWith(url, config)
expect(warn).toHaveBeenCalledTimes(0)
});
})
the #perform method I am testing
class Api {
constructor(auth) {
this._credentials = auth
}
perform = async () => {
try {
return await fetch(this.url, this.config)
} catch(error) {
console.warn('api call failed with error: ', error)
}
}
}
You can set the environment variable CI=true before running jest which will cause it to fail tests on warnings in addition to errors.
Example which runs all test files in the test folder:
CI=true jest ./test
Automated CI/CD pipelines such as Github Actions set CI to true by default, which can be one reason why a unit test will pass on your local machine when warnings are thrown, but fail in the pipeline.
(Here is the Github Actions documentation on default environment variables: https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables)

node.js + express error: cannot read property 'url' of undefined

I'm fairly new to Node.js, installing it to try out the DrupalChat (v7dev) module. I believe this problem is with either node.js or express, as I am beyond the stage where the chat module's settings are loaded. I am faced with the following output when trying to start the chat server
Extension loaded: drupalchat_nodejs.server.extension.js
Started http server.
info - socket.io started
node.js:201
throw e; // process.nextTick error, or 'error' event on first tick
^
TypeError: Cannot read property 'url' of undefined
at Function.handle (/usr/local/lib/node_modules/npm/node_modules/express/node_modules/connect/lib/proto.js:105:18)
at Server.app (/usr/local/lib/node_modules/npm/node_modules/express/node_modules/connect/lib/connect.js:60:31)
at Server.serverListening (/usr/local/lib/node_modules/npm/node_modules/socket.io/node_modules/policyfile/lib/server.js:136:16)
at Server.g (events.js:154:14)
at Server.emit (events.js:64:17)
at Array.1 (net.js:710:10)
at EventEmitter._tickCallback (node.js:192:40)
I remember when express installed, it gave a warning like ".... bugs['web'] should probably be bugs['url']" (I can't remember the prefix)
So is it that the server is trying to read an (API?) variable 'url' but its currently 'web'?
I have all the modules up to date, is it that I should downgrade? Or is there some way of working around this using another module?
EDIT:
line 201 is the last very line (delete authenticatedClients[authData.authToken];)... I just added to whole function for proper context
var authenticateClientCallback = function (error, response, body) {
if (error) {
console.log("Error with authenticate client request:", error);
return;
}
if (response.statusCode == 404) {
if (settings.debug) {
console.log('Backend authentication url not found, full response info:', response);
}
else {
console.log('Backend authentication url not found.');
}
return;
}
var authData = false;
try {
authData = JSON.parse(body);
}
catch (exception) {
console.log('Failed to parse authentication message:', exception);
if (settings.debug) {
console.log('Failed message string: ' + body);
}
return;
}
if (!checkServiceKey(authData.serviceKey)) {
console.log('Invalid service key "', authData.serviceKey, '"');
return;
}
if (authData.nodejsValidAuthToken) {
if (settings.debug) {
console.log('Valid login for uid "', authData.uid, '"');
}
setupClientConnection(authData.clientId, authData, authData.contentTokens);
authenticatedClients[authData.authToken] = authData;
}
else {
console.log('Invalid login for uid "', authData.uid, '"');
delete authenticatedClients[authData.authToken];
}
}
Per #thesnufkin's post, looks like the underlying express version currently pulled is not stable. Roll back to 2.5.9 and you should be good to go:
npm uninstall express
npm install express#2.5.9
As requested,
The v7 chat module from drupal is not stable. You should not use it in production.
Check bugs : http://drupal.org/project/issues/drupalchat?status=All&categories=All
Check forums : http://drupalchat7.botskool.co.in/?q=forum
Still looking for a new maintener:
"New maintainer wanted - please ping beejeebus if you're interested!".
nodejs module has this issue, so I don't think its related to the drupalchat server specifically. Here is the issue for that: http://drupal.org/node/1537702
The option to use node.js as backend in DrupalChat is currently under development. It also depends when (date on which) you downloaded the DrupalChat since the dev code is updated everyday, if new code is committed.
Please raise an issue for the same at this link - http://drupal.org/project/issues/drupalchat?status=All&categories=All.
Thanks,
darklrd

Resources