How to handle errors thrown by render2 in Angular? - javascript

I'm working on this and can't think of a way to handle the error thrown by renderer2.selectRootElement.
This is what my function looks like:
private doSomeAnimation(){
const modalWrapper = this.renderer2.selectRootElement('.modal-wrapper', true);//It fails here
// finally do something with modalWrapper
this.renderer2.addClass(modalWrapper, 'fade-out');
}
and if I open the console I see this error:
global-angular-error-handler.service.ts:49 Error: The selector ".modal-wrapper" did not match any elements
at DefaultDomRenderer2.selectRootElement (dom_renderer.ts:146)
at BaseAnimationRenderer.selectRootElement (animation_renderer.ts:156)
at DebugRenderer2.selectRootElement (services.ts:762)
at ModalComponent.animateClosing (modal.component.ts:39)
....
I also looked at the Docs for Renderer2 and selectRootElement looks like this
selectRootElement(selectOrNode: string|any):any{
let el: any = typeof selectOrNode === 'string'? document.querySelector(selectOrNode) : selectOrNode;
if(!el){
throw new Error(`The selector "${selectorOrNode}" did not match any elements`);
}
el.textContent = '';
return el;
}
As you can see my code fails in line number 1 of my function, so my question is how to NOT show any error in the console if there wasn't any match. I mean how to not show this message in the console
"The selector ".modal-wrapper" did not match any elements"
Can someone help me or point me in the right direction? Thanks a lot in advance!

You could wrap the call into a try/catch
let modalWrapper;
try {
modalWrapper = this.renderer2.selectRootElement('.modal-wrapper', true);
} catch (e) {
// do what you need to do with the exception here.
return;
}

Related

Handling webdriverio timeouts

Here's what I want to accomplish:
check if element "Error" span exists
then do something if it does ===
else check if element "el2" span exists
then do something ====
else
do something
Here's my code
let done = false;
let errorOccured = false;
let isManualStep = false;
do {
try {
console.log('Checking span.label-red=Error...................')
let errorStepExists = $('span.label-red=Error').isExisting();
if (errorStepExists) {
console.log('Error encountered...................')
done = true;
}
} else {
console.log('Error not encountered...................')
let el2Exists = $('span>td.col-md-2=Waiting').isExisting();
if (mel2Exists) {
console.log('Encountered...................')
}
} catch (e) {
console.log(e);
}
}
while (!done);
It doesn't seem to go to the catch block if element doesn't exist and it fails my test instead with a timeout error.
Error: Timeout of 20000ms exceeded. The execution in the test "xxxxxx" took too long. Try to reduce the run time or increase your timeout for test specs (https://webdriver.io/docs/timeouts.html).
Not sure how to best way to achieve your goal in your programming language binding, however the best way in java is to use the "findElements(By locator)" method of WebDriver interface.
This method returns a List. You then check for the existence of your WebElement by examining the size of this list. (If the size is not 0, your WebElement is present).
Hope this helps you come by with a similar approach in your language binding.

Javascript Custom Exception

I have tried for a couple of days researching on how to create a custom exception in a try/catch.
Here is what I am attempting to do:
I have an included JS file in my html page. The JS file defines a custom object, as well as defining methods for the object.
Next, in the html page I am doing the following:
try {
MyObj = new CustomObj; //from the included JS file.
MyObj.CustomMethod(); //also from the included JS file.
} catch(e) {
alert("Error in either the create of the object, or the method. Error is " + e.description)
}
I need to be able, within the code for the CustomMethod(), to set the Error Object's properties that are captured in the catch statement. For example:
CustomMethod = function{
try{
document.getelementById("field1").value = "my value";
} catch(err) {
//Set the return error
ReturnErr.description = "There was an error!";
}
};
Can this be done? From what I have tried, I have used the throw statement, but it does not effect the Error Object, thus the catch section is never triggered. In face, the custom message is only shown in the Console.
Thanks ahead of time.
Try:
function MyException(_message, _data) {
this.message = _message;
this.data = _data;
this.name = "MyException";
}
Usage
try{
//...
}
catch(_error){
throw new MyException(message, _error);
}
Hope it will help you to sort things out

javascript - an assert function that doesnt require you to enter an error message

Implementing an assert in javascript is not difficult:
assert = function(expression,errorMessage){
if (!expression){
errorMessage = errorMessage || "(no msg)";
throw new Error("assert failed: "+errorMessage);
}
return true;
};
However, using this version of assert is tiresome because you have to have a meaningful error message for every test case:
var types = {isNumber:function(x){return typeof x === "number" && isFinite(x)}}
assert(types.isNumber(1)===true,"types.isNumber(1)===true");
assert(types.isNumber(NaN)===false,"types.isNumber(NaN)===false");
My question is that is there a way to implement the assert function such that it only takes one expression and it can return meaningful error message if that expression is not met? Like:
assert(SOMETHING_that_is_not_true); // throw Error: SOMETHINGELSE that refers to this particular assertion
assert(SOMETHING_that_is_not_true2); // throw Error: SOMETHINGELSE2 that refers to this different assertion
It's a bit more code than a simple expression for each assertion, but how about this?
assert = function(expression){
if (!expression()){
errorMessage = expression.toString() || "(no msg)";
throw new Error("assert failed: "+errorMessage);
}
return true;
};
assert(function() { return 'b' == 'a' });
I just want to add this as it will work. But it is
Not advised
As it uses eval, which is, juck. But it is useful if you don't face it to the client. (What am I saying? It is not advised. End of that. But it does work.)
function assert(expression){
var success = eval(expression);
if(!success) throw new Error("assert failed: "+ expression);
else return true;
}
Then you can do
assert("types.isNumber(1)===true");
So te reiterate, use #James Thorpe s code (hopefully) above.

What's the best way to test for SyntaxError exceptions in QUnit?

I have some JSON data inside of an HTML data element:
<div id="ps-data" data-ps="
{
"teacherId": 12345678
},
"></div>
I parse it using jQuery's parseJSON function, but if I pass it invalid JSON, I get a SyntaxError exception. In QUnit, this shows up as a global failure, but I'd like it to fail in one of my test cases. What's the best way to do so?
My parsing code looks like:
$.parseJSON($('#ps-data').data().ps);
You could do something like this:
var exeptionReached = false;
try {
$.parseJSON($('#ps-data').data().ps);
} catch(e) {
exceptionReached = true;
}
console.log(exceptionReached); //will be true if `parseJSON()` threw an exception
Use qunit to assert exception was reached... or you can save something from the exception object if you want to assume something specific about it, for example:
var ex;
try {
$.parseJSON($('#ps-data').data().ps);
} catch(e) {
ex = e;
}
console.log(ex.message); // something like "Unexpected token ,"
You'll want to check that ex is defined before accessing properties of course. I think you should be able to see how you can test whether or not an exception happened and how to test specifics about that exception if you want... but let me know if you have any extra questions.
JSFiddle example
Here's the full example of what I'm doing based on smerny's answer.
function testParse() {
var exceptionMsg;
try {
var data = $j.parseJSON($j('#ps-data').data().ps);
} catch (e) {
exceptionMsg = e.message;
}
return exceptionMsg;
}
strictEqual(testParse(), undefined, 'ps data parses with no exceptions');
This will show me the exception message when it fails.

throwing a debug from chrome extension content script

Short version
Trying to write a debug command that returns the call stack, minus the current position. I thought I'd use:
try {
throw new Error(options["msg"])
} catch (e) {
e.stack.shift;
throw (e);
}
but I don't know how to do it exactly. apparently I can't just e.stack.shift like that. Also that always makes it an Uncaught Error — but these should just be debug messages.
Long version
I decided I needed a debug library for my content scripts. Here it is:
debug.js
var debugKeys = {
"level": ["off", "event", "function", "timeouts"],
"detail": ["minimal", "detailed"]
};
var debugState = { "level": "off", "detail": "minimal" };
function debug(options) {
if ("level" in options) {
if (verifyDebugValue("level", options["level"]) == false)
return
}
if ("detail" in options) {
if (verifyDebugValue("detail", options["detail"]) == false)
return
}
console.log(options["msg"]);
}
function verifyDebugValue(lval, rval){
var state = 10; // sufficiently high
for (k in debugKeys[lval]) {
if (debugKeys[lval][k] == rval) {
return true;
}
if (debugKeys[lval][k] == debugState[lval]) { // rval was greater than debug key
return false;
}
}
}
When you using it, you can change the debugState in the code to suit your needs. it is still a work in progress but it works just fine.
To use it from another content script, just load it in the manifest like:
manifest.json
"content_scripts": [
{
"js": ["debug.js", "foobar.js"],
}
],
and then call it like:
debug({"level": "timeouts", "msg": "foobar.js waitOnElement() timeout"});
which generates:
foobar.js waitOnElement() timeout debug.js:17
And there is my problem. At the moment, it is using the console log and so all the debug statements come from the same debug.js line. I'd rather return the calling context. I imagine I need something like:
try {
throw new Error(options["msg"])
} catch (e) {
e.stack.shift;
throw (e);
}
but I don't know how to do it exactly. apparently I can't just e.stack.shift like that. Also that always makes it an Uncaught Error — but these should just be debug messages.
You can't avoid mentioning the line in your debug.js, because either using throw (...) or console.log/error(...) your debug.js will be issuing the command.
What you can do, is have some try-catch blocks in your code, then in the catch block pass the error object to your debug function, which will handle it according to its debugState.
In any case, it is not quite clear how you are using your debug library (and why you need to remove the last call from the stack-trace, but you could try something like this:
Split the stack-trace (which is actually a multiline string) into lines.
Isolate the first line (corresponding to the last call) that is not part of the error's message.
Put together a new stack-trace, with the removed line.
E.g.:
function removeLastFromStack(stack, errMsg) {
var firstLines = 'Error: ' + errMsg + '\n';
var restOfStack = stack
.substring(firstLines.length) // <-- skip the error's message
.split('\n') // <-- split into lines
.slice(1) // <-- "slice out" the first line
.join('\n'); // <-- put the rest back together
return firstLines + restOfStack;
}
function myDebug(err) {
/* Based on my `debugState` I should decide what to do with this error.
* E.g. I could ignore it, or print the message only,
* or print the full stack-trace, or alert the user, or whatever */
var oldStack = err.stack;
var newStack = removeLastFromStack(oldStack, err.message);
console.log(newStack);
//or: console.error(newStack);
}
/* Somewhere in your code */
function someFuncThatMayThrowAnErr(errMsg) {
throw new Error(errMsg);
}
try {
someFuncThatMayThrowAnErr('test');
} catch (err) {
myDebug(err);
}
...but I still don't see how removing the last call from the trace would be helpful

Categories