Watch console for errors - console

I have an app using canvas elements, which are difficult to test with javascript but it does throw messages to the console.
How can I watch for errors written to the console?
I tried monkey patching the window console, but it's not working.
const messages = []
window.console.error = (msg) => {
messages.push(msg)
})
// actions causing error
expect(messages.length).to.eq(0)

You can watch console messages with Cypress cy.spy(), ref docs
let spy;
Cypress.on('window:before:load', (win) => {
spy = cy.spy(win.console, "error")
})
// actions causing error
cy.then(() => {
expect(spy).not.to.be.called
})

Related

Nuxt plugin not available in Vuex's 'this' in Firebase production (ERROR: this.$myPlugin is not a function)

I'm trying to upload my nuxt app to Firebase as cloud function. The problem is that in the nuxtServerInit action I'm trying to call a plugin function, which apparently is not yet defined at that moment, because an error is thrown: (ERROR: this.$myPlugin is not a function). The code works in dev mode, it's just after upload to Firebase it fails.
The setup is as follows:
myPlugin.js
let env, auth, app, $store;
export default (context, inject) => {
env = context.app.context.env;
auth = context.app.$fire.auth;
app = context.app;
$store = context.store;
inject('myPlugin', myPlugin);
};
async function myPlugin(...) {... }
nuxt.config.js
plugins: [
{ src: '~/plugins/myPlugin', mode: 'all' }, // with no mode specified it fails too
],
vuex index.js
export const actions = {
async nuxtServerInit({ dispatch, commit }, { req }) {
const tl = await dispatch("initAction");
return tl;
}
}
vuex someModule.js
const actions = {
initAction({ commit }) {
return this.$myPlugin(...).then(...) // this line throws '$myPlugin is not a function' error
}
}
What can be the reason for the different behaviour in dev and in prod modes and how could I fix the problem?
UPDATE:
After further testing I established that the problem is not caused by the nuxtServerInit timing. I moved the call of the initAction from nuxtServerInit to a page's created hook. However the same error appears: this.$query is not a function.
The problem occured, because js files were not getting fully loaded due to CORB errors caused by incorrect configuration. Details described in this question.

Cloudflare Worker times out for the client, but all the work completes and no timeout error given (inspected with console.log/ `wrangler tail`)

My published Cloudflare Worker (wrangler publish --env environment_name) is timing out for clients, but not when
running locally (e.g. by using cfworker, a nice tool to emulate cloudflare workers locally)
or running in preview (wrangler preview --env environment_name).
A summary of my worker:
addEventListener('fetch', async (event) => {
const fetchEvent = event as FetchEvent
const results = await doSomeWork() // returns a promise
return fetchEvent.respondWith(new Response(JSON.stringify(results)))
})
My wrangler tail (production logs) output does complete (after I placed console.log statements in doSomeWork. There were no errors, and I got {"outcome":"ok"... in wrangler tail. I would have expected to get error code 1102 (Worker exceeded CPU time limit.) if time-out was happening.
It turns out that addEventListener cannot be passed an async function (or one that returns a promise). The fetchEvent.respondWith does accept a promise however. This is not written in the documentation, but I discovered this in lib.webworker.d.ts.
To do asynchronous work, you must return a promise to fetchEvent.respondWith instead:
So your alternatives are to:
Pass a promise to respondWith
addEventListener('fetch' (event) => {
const fetchEvent = event as FetchEvent
const responsePromise = doSomeWork().then((results) => new Response(JSON.stringify(results))
return fetchEvent.respondWith(responsePromise))
})
Or pass the result of an async function to respondWith (still a promise, I told you, you must return a promise)
addEventListener('fetch' (event) => {
const fetchEvent = event as FetchEvent
const responsePromise =
return fetchEvent.respondWith(async () => {
// I would put this async function in a different file (handlers.ts/.js), and name it `doSomeWorkHandler` to make it more readable though
const results = await doSomeWork()
return new Response(JSON.stringify({hello: "world"}))
}))
})
Why no timeout error?
The reason the timeout error doesn't happen is because even though Cloudflare Workers limits your CPU execution time to 10ms on the free plan, it doesn't stop your worker because you're not using the CPU in this bug/ edge case. It's doing nothing.

How to fix the error : your application id may be incorrect. If the error persists, contact support#algolia.com

I want to send cloud firestore data to algolia to enable full-text search. Firebase cloud function log is showing an error about application id. I am not able to understand this error and how to fix this.
name: 'RetryError',
message: 'Unreachable hosts - your application id may be incorrect. If the error persists, contact support#algolia.com.'
This is my index.js file
exports.addFirestoreDataToAlgolia =
functions.https.onRequest((req, res) => {
var arr = [];
admin.firestore().collection("tags").get()
.then((docs) => {
docs.forEach((doc) => {
let user = doc.data();
user.objectID = doc.id;
arr.push(user);
})
const client = algoliasearch(ALGOLIA_ID, ALGOLIA_ADMIN_KEY);
const index = client.initIndex(ALGOLIA_INDEX_NAME);
return index.saveObjects(arr, (err, content) => {
if (err) {
res.status(500);
}
else {
res.status(200).send(content);
}
})
})
.catch( err => {
console.log(err);
})
})
Outbound requests (outside of Google services) can only be made from functions on a paid plan (https://firebase.google.com/pricing).
Reason for the wrong appID error is that the Algolia is trying to resolve a dns using your appID, which fails. See https://github.com/algolia/algoliasearch-client-javascript/issues/587#issuecomment-407397688
You have to move off of the free Spark plan in order to call out to Algolia from your function..
I also got this error with NextJS, it was working fine with react but then when I moved to NextJs I got the error.
Turns out it was my .env variables that were not being passed correctly to the client/browser. Renaming the variables from REACT_APP_<variable name> to NEXT_PUBLIC_<variable name> to make them available to the browser as per the NextJs documentation fixed the issue.
NEXT_PUBLIC_ALGOLIA_APP_ID=xxxxxx
NEXT_PUBLIC_ALGOLIA_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NEXT_PUBLIC_ALGOLIA_ADMIN_API_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxx

Output console logs from page.evaluate to local terminal?

How can I output console logs from page.evaluate to local terminal?
await page.evaluate(() => {
console.log("test"); // <-- I want this message to show in my local terminal
I am running my code locally on a MacOS computer.
The following solutions I have found in github issues have not worked:
solution 1
const browser = await puppeteer.launch({
'args': ['--disable-dev-shm-usage', '--disable-software-rasterizer'],
dumpio: true
});
// output:
// ERROR:gpu_process_transport_factory.cc(967)] Lost UI shared context.
solution 2
const browser = await puppeteer.launch({
'args': ['--disable-dev-shm-usage', '--disable-software-rasterizer']
});
page.on('console', msg => {
for (let i = 0; i < msg.args.length; ++i)
console.log(`${i}: ${msg.args[i]}`);
});
// output:
// nothing
Just started with Puppeteer myself. Couldn't figure it out right away, but after trying a few things, this worked for me.
const names = await page.evaluate(() => {
let names = document.querySelectorAll("#lnkBEName");
console.log(names);
return names;
})
console.log(names);
Then console.log inside the function block doesn't work. However, the last line, outside the block works. Hope this helps someone.

Mongoose asynchronous .save and callback

This is one of those problem that you can explain but do not know how to fix it. I have a simple store method:
exports.store = async (req, res) => {
const mydata = new MyModel(req.body)
await mydata.save(function(err,user) {
res.location('/mydata/id/' + user._id)
})
res.status(201).json({ data: userdata })
}
When it runs, I get the following error:
events.js:182
throw er; // Unhandled 'error' event
^
Error: Can't set headers after they are sent.
at validateHeader (_http_outgoing.js:489:11)
at ServerResponse.setHeader (_http_outgoing.js:496:3)
at ServerResponse.header (.../node_modules/express/lib/response.js:730:10)
at ServerResponse.location (.../node_modules/express/lib/response.js:847:15)
at .../src/controllers/users-controller.js:26:13
at .../node_modules/mongoose/lib/model.js:3919:16
at .../node_modules/mongoose/lib/services/model/applyHooks.js:162:20
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
Process finished with exit code 1
I appears that the callback function runs separately and asynchronously because the res.status(201).json({ data: userdata }) seems to be producing the error and does not let me set the location header.
I've looked around for how to set the location header but none of the answers are like what I'm trying to do. This seems like something that should have been done before...? I'm looking for some help on how to do this...
You are mixing up two way of thinking :
Promises (with async/await in your case)
Callback
Use only one
try {
const user = await mydata.save();
res.location(`/mydata/id/${user._id}`);
// Other stuff ...
} catch(err) {
// Handle the errors
}
here you get an article about Promises into mongoose.

Resources