Sometimes there is a modal window that pops up. I have this try catch to handle it and it works in headless mode. However, when I'm in VSCode, it stops when the error is thrown.
await test.step('Optionally click continue', async () => {
try {
page.getByRole('cell', { name: 'Continue' }).click({ timeout: 10000 });
} catch (error) {
}
});
Error Screenshot
Is there a playwright preferred way to handle this that doesn't throw an exception? The playwright extension stops on exceptions to help debug. In this case, I would prefer a way to optionally handle a button without an exception being thrown.
You can use:
if page.isVisible('role=cell[name="Continue"i]') {
//Whatever
}
Related
can I throw error and use await word in one statement using AND operator, the following code explains well my request :
throw new Error() && await client.end().
This latter works fine till now, and for my question, is this the better form of writing this and will it create problems in some cases.
My main purpose is to close the Data Base connection and throw the Error.
for such use cases I think the finally block is the right solution. See on the mozilla docs here. In your case it would be something like
try {
// stuff that can throw an error
} catch {
// handle the error case
} finally {
// in any case, close the connection
await client.end()
}
Or, if you want to keep the connection open when there's no error, just move the close line in the catch block:
try {
// stuff that can throw an error
} catch {
// handle the error case
await client.end()
}
I am not a JavaScript guy (can only write simple JS function), I am trying to debug a code with the JS where my backed system is passing the correct values but I am getting an error while processing the code on the UI. Here is the JS code
this.session.onvalidatemerchant = function (event) {
this.performAuthorizeMerchantRequest(event.validationURL)
.then(function (merchantSession) {
this.session.completeMerchantValidation(merchantSession);
alert("jdshhdjhjdhh");
}.bind(this))
.catch(this.showPaymentError.bind(this));
}.bind(this);
Here is the error handling function
showPaymentError: function () {
//showing a message on the UI
}
I have already verified the data being passed from my backed service is correct, I don't see the following alter alert("jdshhdjhjdhh");. There seems to be issue with the completeMerchantValidation method but I am not sure what is the root cause for failure.I tried to change my error message with something like this
showPaymentError: function (e) {
console.log("*****111"+e)
}
but getitng the following output in the console *****111TypeError: Type error. Is there a way I can print the error from the completeMerchantValidation. Even tried to add try and catch around that method call but getting js compilation error
Try this. the try catch will handle the potential error which come from performAuthorizeMerchantRequest or completeMerchantValidation.
this.session.onvalidatemerchant = async ({ validationURL }) => {
try {
const merchantSession = await this.performAuthorizeMerchantRequest(validationURL)
this.session.completeMerchantValidation(merchantSession)
alert('jdshhdjhjdhh')
} catch (error) {
console.error('Oh oh, an error happened', error)
this.showPaymentError(error);
}
}
The root cause is a TypeError that is being thrown at some point in the Promise's lifecycle.
Given that console.log("*****111"+e) prints *****111TypeError: Type error, we are dealing with a TypeError.
Unfortunately "Type error" isn't the most useful debugging data :(
Maybe try printing the stacktrace?
https://developer.mozilla.org/en-US/docs/Web/API/Console/trace
I am doing processing using Puppeteer and I am closing the browser like using browser.close() for example something like this
const browser = await puppeteer.launch({
headless: true,
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
});
try {
// more processing
browser.close();
// more processing
} catch(err) {
console.log(err);
browser.close();
}
I am using browser.close(); in catch block, but sometimes the browser.close() is already executed in try block when the exception occurs.
I want to know if there is a way to check if browser.open? and issue browser.close() only in that case.
Any help in this would be really great. Thanks.
Take a look about try...catch
You should add finally block and add there browser close :)
The finally-block contains statements to execute after the try-block and catch-block(s) execute, but before the statements following the try...catch...finally-block. Note that the finally-block executes regardless of whether an exception is thrown. Also, if an exception is thrown, the statements in the finally-block execute even if no catch-block handles the exception.
Edit 1
After understanding that issue is detecting if browser is closed I edit and input solution for that problem puppeteer : how check if browser is still open and working
I am modifying a node.js library to support true asynchronous operations.
I am having troubles with Mocha and Chai to make this (a similar) test pass.
it('should throw an error', function() {
expect(function() {
process.nextTick(function() {
throw new Error('This is my error');
});
}).to.throw(Error);
});
The problem is - because of the nextTick - that the Error is thrown out of scope of it and besides the test failing, Mocha also outputs the below.
Uncaught Error: This is my error
What is the proper way to structure this test in order to make it succeed?
Hmm... in a full-fledged application what I'd do is probably use something like Sinon to check that the method that should throw an error has been called and is throwing.
In code where you cannot do this, then the following method would trap the exception:
var expect = require("chai").expect;
var domain = require("domain");
it('should throw an error', function(done) {
var d = domain.create();
d.on('error', function (err) {
// Exit the current domain.
d.exit();
// We must execute this code at the next tick.
process.nextTick(function () {
console.log(err); // Just to show something on the console.
expect(err instanceof Error).to.be.true;
done();
});
});
d.run(function () {
process.nextTick(function() {
throw new Error('This is my error');
});
});
});
This code creates a "domain" stored in d. A domain will emit error events on uncaught exceptions that happen in it so we run the test inside the domain (d.run(...)) we've created and wait for an exception to happen (d.on('error', ...). We check that it is an Error object. (In a real test, I'd also check the error message.) When we are finished we call done() to tell Mocha that the asynchronous test is over.
The handler for error events calls d.exit(). This is to make it so that Mocha can catch the error normally if the assertion (expect(err instanceof Error)...) turns out to fail. If we do not exit the domain, then the domain will trap the error. Also, the check itself must be performed on the next tick to be outside the d domain.
Is Using domain A Problem?
NO!
The documentation for domain comes with some warnings about shutting down operations once an uncaught exception is caught when running an ongoing process, like a server. Then the thing to do is to clean what can be cleaned and exit as soon as possible. However, using domain in a test does not differ from what Mocha is already doing. The way Mocha catches unhandled exceptions in asynchronous code is by using process.on('uncaughtException'. Upon catching an unhandled exception Mocha marks the current test as failed and continues. Yet the documentation regarding uncaughtException says "Don't use it, use domains instead. If you do use it, restart your application after every unhandled exception!"
Ergo, anyone who has a problem with using domain should not be using Mocha in the first place.
You're trying to catch an exception on the incorrect function, the container for the function that throws. Also, because the function is wrapped in nextTick it is executed in a different stack and therefore the exception cannot be captured (this is simply a JS thing unfortunately).
Try this instead:
it ('should throw an error', function (done) {
process.nextTick(function () {
var myFn = function () { throw new Error() };
expect(myFn).to.throw(Error);
// Tell mocha the test is complete
done();
});
});
Update: There is no proper way to structure this test to make it pass as you cannot catch the exception in this scenario. Perhaps update your code to use callbacks to handle errors:
function doSomethingUnsafe() {
try {
// Run code here that may cause exceptions...
callback(null, 'Woohoo! No errors!');
} catch (e) {
callback (e, null);
}
}
Does anyone know if there a way to disable error handling by Mocha?
I'd really like to let the exception bubble up and be handled by the browser during debugging.
Update:
The context is this.
- Some code throw's an unexpected error.
- I would like to disable "try/catch" (something like jasmine's tests do) and be thrown into the debugger in chrome.
This way I can inspect the current state of the application at that moment.
It sounds like there isn't something built in, and I will need to manually do this each time I get some odd error in a test. Maybe by wrapping my code with
try {
somethingThatBreaks();
} catch(e) {
debugger;
}
Mocha installs its own onerror handler to trap exceptions that may occur in asynchronous code. You can disable it with:
window.onerror = undefined;
This is dangerous. You should do this only when you must absolutely do so. If you make this a routine thing, Mocha will completely miss errors that happen in asynchronous code.
If what you want to do is let exceptions in synchronous code bubble up, I'm not seeing what this would accomplish. If you want to inspect the exception before Mocha touches it, a try...catch block wrapping your test will do this.
Mocha's error handling is contained in the following code:
if (this.async) {
try {
this.fn.call(ctx, function(err){
if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
done();
});
} catch (err) {
done(err);
}
return;
}
// sync
try {
if (!this.pending) this.fn.call(ctx);
this.duration = new Date - start;
fn();
} catch (err) {
fn(err);
}
You could possibly throw the error with the catch (or remove the try..catch entirely) however it would most likely break the test suite if a test fails.
mocha.options.allowUncaught=true
But in this case, the rest of the tests will break if the error is not caught within mocha. Disabling try{} catch(){} in mocha will only be useful when debugging.
To create a test, I suggest using the construction
(for browser)
try{
throw new Error()
} catch (e){
// Let's say it's called in a yor error listeners.
e.handler=()=>{
done(e)
}
let event= new ErrorEvent('error',{error:e})
window.dispatchEvent(event);
}