What is the difference between these two statements, and is there a good reason to use one over the other?
throw Error("msg");
console.error("msg");
In my limited experience, I've only really seen throw Error() used. Is there any particular reason why?
Also, is there an equivalent to console.warn() in the same fashion?
throw ... raises an exception in the current code block and causes it to exit, or to flow to next catch statement if raised in a try block.
console.error just prints out a red message to the browser developer tools javascript console and does not cause any changes of the execution flow.
Some of the Differences are:
throw Error("msg"):
Stops js execution.
Mostly used for code handling purpose.
Can alter main flow of execution.
This syntax is mostly same for all browser as this is specified and validated by W3C.
console.error("msg"):
It just shows output in Red color at Browser console
It is mostly used to print values for debugging purpose.
Cannot harm main flow of execution.
This Syntax sometimes vary according to vendor browser and not standardized by W3C.
i.e. For IE accepted syntax is window.console.debug("msg")
Throw is for actually changing the control flow (jumping out of the current context and up to an error handler) for handling errors programmatically. The console statement is just for debugging and printing text to the error console. You may see them used in conjunction, for example:
var doSomethingDangerous = function(response) {
if (isMalformed(response)) {
throw Error('Response is malformed.');
}
process(response);
};
var sendAsyncRequest = function() {
var request = buildAsyncRequest();
request.sendThen(function (response) {
try {
doSomethingDangerous(response);
} catch (e) {
console.error(e);
doSomeAdditionalErrorHandling();
}
});
};
Related
I have created a public Web App with access to my private spreadsheet data. I can catch and log exceptions intry..catch, but:
is it possible to catch all unhandled exceptions, like browsers window.onerror?
can I view logs of unhandled exceptions somewhere?
by exceptions like "Service invoked too many times" my app is even not getting run, so here I definitely can`t handle the exceptions. Is there logs with such kind of exceptions?
These are so simple questions, so that I'm bit confused to ask them, but after hours of research I could not find the answers.
Thank you in advance.
These are issues that are being addressed currently. Right now in the Apps Script Early Access Program are two new additions that handle these cases. The first is native integration with stackdriver logging and the addition of google.script.run.withLogger().
First off for now you need to apply for the EAP:
https://developers.google.com/apps-script/guides/apps-script-eap
Stackdriver Logging:
To log to stackdriver the console object has been added to the server side.
code.gs
console.log('This will log to stackdriver')
Check out the docs for all the methods of console.
https://developers.google.com/apps-script/guides/logging#stackdriver_logging
Example from the docs:
function measuringExecutionTime() {
// A simple INFO log message, using sprintf() formatting.
console.info('Timing the %s function (%d arguments)', 'myFunction', 1);
// Log a JSON object at a DEBUG level. The log is labeled
// with the message string in the log viewer, and the JSON content
// is displayed in the expanded log structure under "structPayload".
var parameters = {
isValid: true,
content: 'some string',
timestamp: new Date()
};
console.log({message: 'Function Input', initialData: parameters});
var label = 'myFunction() time'; // Labels the timing log entry.
console.time(label); // Starts the timer.
try {
myFunction(parameters); // Function to time.
} catch (e) {
// Logs an ERROR message.
console.error('myFunction() yielded an error: ' + e);
}
console.timeEnd(label);
}
In addition you can also check Log Exceptions in the scripts properties. This will generate a stackdriver entry every time any error occurs in your script.
Error recovery in a web app
To recover in a web app from a failure you have access to the withFailureHandler() method found in the google.script.run object. With this you can register a callback in the event your script hits an exception.
Full documentation can be found at:
https://developers.google.com/apps-script/guides/html/reference/run
If you are doing server side checks with try...catch you may be getting an exception but gracefully handling it. In this case withFailureHandler() will not execute and onSuccessHandler() propably isnt the best place to handle errors. In the EAP there is now a withLogger method to google.script.run. For now there no documentation for google.script.run.withLogger(). I found it by digging through devtools. withLogger() allows you to register a function as a callback when ever a stackdriver entry is created. This is particularly helpful when you have log exceptions checked in your script properties. In this sense it is a bit like withFailureHandler() but it can be triggered by any stackdriver entry you add though the server-side console object.
index.html
<script>
google.script.run
.withSuccessHandler(function(){console.log('OK')})
.withFailureHandler(function(e){console.error(e)})
.withLogger(function(e){console.warn("The following log was generated:"+e)})
.serverFunctionCall();
</script>
code.gs
function serverFunctionCall(){
console.log("This log will generate a callback");
return true;
}
Try/catch at global scope will work, however any let/const container will not be globally exposed.
To fix this, you can use var within the try/catch at global scope
I'm analyzing some code on a website and I came across the following anonymous function followed by a try catch statement. I'm just wondering what the try catch statement is doing at the end there. Is it pre-loading the url so thats it loads more quickly then the anonymous function goes? Also, whats the point is it's not catching any errors.
(function() {
var fired = false;
bsnPop.add("http://www.someurl.com", {
under: !noPopunder,
newTab: false,
forceUnder: true,
shouldFire: function() {
return !fired;
},
cookieExpires: -1,
afterOpen: function(url) {
createCookie();
fired = true;
doSecondPop();
}
});
})();
try {
var hint = document.createElement("link");
hint.rel = "dns-prefetch";
hint.href = "http://www.someurl.com";
document.head.appendChild(hint);
var hint = document.createElement("link");
hint.rel = "preconnect";
hint.href = "http://www.someurl.com";
document.head.appendChild(hint);
} catch (e) {}
With reference to the link types list on MDN, "dns-prefetch" and "preconnect" are listed as experimental. They do not appear in the list of "rel" values for link types of link elements in HTML5
So the code is using experimental technology on the web which might throw an error in some browsers. To prevent stopping the application and logging an exception on the console, the code is placed in a try block with a catch block that ignores the error.
In answer to question details, the anonymous function in the IIFE is invoked and passes an object containing parameters and callbacks in a call to bsnPop.add. It does not appear to create a popup window at this stage.
Next code within the try block attempts to speed up access to the web site by requesting DNS lookup of the website's name in advance, and to open a connection to the site before attempting to retrieve content.
The code is placed in the try block to accommodate the possibility of a browser throwing an exception if the requested operations are not supported. The application does not consider lack of support an error and wants to continue anyway.
The end result is that if dns-prefetch or preconnect are supported the browser can take the hint and perform the operations. If they are not supported any error generated is ignored and code continues at the next statement - connecting to the website later will have to proceed at normal speed.
Sometimes some (non critical) errors come out during the executing of my Javascript code.
While I'm aware that a workaround is not the best solution, I'm stuck on a blocking error which I need to get rid of.
Since the error is basically can't read [0] of undefined (the array doesn't exist), what I'd like to is something like:
try{
var abc = array[0];
} catch(e){
// continue execution
// skip to the end of this function
// run a different a function [e.g. alternativeFunction()]
// ignore the error
}
the try...catch block works, it prints the error but my Javascript code is being blocked.
I'm having to make a Javascript API that is the public interface to a C-based API that has enumerations and required parameters. Javascript, being a loosely typed language, wouldn't offer the same kind of compiler warnings one might get when using a C-based API.
My question is when making a Javascript wrapper around the C API, is it expected in the Javascript culture that one would receive a TypeError when passing invalid data or would it be more expected for the API to output a message to the console and ignore the error?
Here's some sample code for the API...
var Foo = (function() {
var foo = {
Enum: {
First: {value: 0},
Second: {value: 1},
Third: {value: 2}
},
bar: function(eenoom, aNumber) {
if (!eenoom) {
throw new TypeError("bar: You must specify the 'eenoom' parameter");
return;
}
if (!aNumber || typeof aNumber != 'number') {
throw new TypeError("bar: You must specify the 'aNumber' parameter (as a number)");
return;
}
for (var key in foo.Enum) {
if (foo.Enum.hasOwnProperty(key)) {
if (foo.Enum[key] === eenoom) {
console.log("You did it!");
return;
}
}
}
throw new TypeError("bar: You must use the Foo.Enum enumeration");
}
}
// So no one can mess with our enums
Object.freeze(foo.Enum);
return foo;
})();
Foo.bar(Foo.Enum.First, 20);
Foo.bar({value: 0}, 20); // Throws a TypeError
Note the use of TypeError. Is this an expected way for a Javascript API to behave?
I mainly do the following:
In synchronous public APIs I always check parameters and throw the appropriate error. Not only TypeError but also other errors as appropriate.
Generally I throw errors in exceptional cases - i.e. not fitting the thought-out execution flow.
In asynchronous APIs I report errors via an error callback/reject function.
I think console.log(...) and go on is not a good idea. If the call did not met the pre-conditions of the API, the API contract is broken from the very start. (Unless the contract is, specifically "yes, I can handle bad input" which is quite decadent.)
In this case nothing that you do afterwards will be correct. So throw an error and break off.
As an API consumer I'd be grateful for a thrown error with a good stack trace and a meaningful error message - much more that for just a meaningfull error message in the console (which I may or may not notice).
If the programmer has written code that will never work (not provided required parameters, sent the wrong type or order of parameters, etc...), then you want the code to fail immediately, fail visibly, clearly tell the programmer what is wrong and provide a stack trace that shows exactly where the offending code is.
The cleanest way to do that in Javascript is by throwing an appropriate type of error with a meaningful description. The very first time this code is executed, it will fail and the developer will immediately know they have done something wrong. This is what you want. Anything else increases the chances that the developer does not immediately realize the programming mistake they've made or even if they realize something isn't working, it might take them significantly longer to figure out why it isn't working.
A console.log() statement has these drawbacks:
It may not be seen immediately or at all.
It doesn't provide a stack trace so it may not be obvious what specific part of the caller's code is causing the error.
Since the app may not fail noticeably, it may appear that nothing is wrong or nothing serious is wrong when in reality there is a major programming mistake that must be fixed.
This question already has answers here:
How to terminate the script in JavaScript?
(25 answers)
Closed 7 years ago.
Is it possible in some way to stop or terminate JavaScript in a way that it prevents any further JavaScript-based execution from occuring, without reloading the browser?
I am thinking of a JavaScript equivalent of exit() in PHP.
Short answer:
throw new Error("Something went badly wrong!");
If you want to know more, keep reading.
Do you want to stop JavaScript's execution for developing/debugging?
The expression debugger; in your code, will halt the page execution, and then your browser's developer tools will allow you to review the state of your page at the moment it was frozen.
Do you want to stop your application arbitrarily and by design?
On error?
Instead of trying to stop everything, let your code handle the error. Read about Exceptions by googling. They are a smart way to let your code "jump" to error handling procedures without using tedious if/else blocks.
After reading about them, if you believe that interrupting the whole code is absolutely the only option, throwing an exception that is not going to be "caught" anywhere except in your application's "root" scope is the solution:
// creates a new exception type:
function FatalError(){ Error.apply(this, arguments); this.name = "FatalError"; }
FatalError.prototype = Object.create(Error.prototype);
// and then, use this to trigger the error:
throw new FatalError("Something went badly wrong!");
be sure you don't have catch() blocks that catch any exception; in this case modify them to rethrow your "FatalError" exception:
catch(exc){ if(exc instanceof FatalError) throw exc; else /* current code here */ }
When a task completes or an arbitrary event happens?
return; will terminate the current function's execution flow.
if(someEventHappened) return; // Will prevent subsequent code from being executed
alert("This alert will never be shown.");
Note: return; works only within a function.
In both cases...
...you may want to know how to stop asynchronous code as well. It's done with clearTimeout and clearInterval. Finally, to stop XHR (Ajax) requests, you can use the xhrObj.abort() method (which is available in jQuery as well).
You can make a JavaScript typo :D (thinking outside the box here)
thisFunctionDoesNotExistAndWasCreatedWithTheOnlyPurposeOfStopJavascriptExecutionOfAllTypesIncludingCatchAndAnyArbitraryWeirdScenario();
Or something like:
new new
Something like this might work:
function javascript_abort()
{
throw new Error('This is not an error. This is just to abort javascript');
}
Taken from here:
http://vikku.info/codesnippets/javascript/forcing-javascript-to-abort-stop-javascript-execution-at-any-time/
I do:
setTimeout(function() { debugger; }, 5000)
this way I have 5 seconds to interact with UI and then in stops. Las time I used was when I needed to leave custom tooltip visible, to do some styling changes.
No.
Even if you throw an exception, it will only kill the current event loop. Callbacks passed to setTimeout or DOM/XMLHttpRequest event handlers will still run when their time comes.
I am using
return false;
if I want to abort from JavaScript from running further downwards.
If you're in a function you can exit it using return; but that doesn't stop execution of the parent function that called that function.
You can call return early in a function, and at least that function will stop running. You can also just use throw '' to cause an error and stop the current process. But these won't stop everything. setTimeout and setInterval can make delayed functions and functions that run on a time interval, respectively. Those will continue to run. Javascript events will also continue to work as usual.
I know this is old, but I wanted to do this and I have found, in my opinion, a slightly improved solution of the throw answers. Just temporary supress the error messages and reactivate them later using setTimeout :
setTimeout(function() {
window.onerror = function(message, url, lineNumber) {
return false;
};
}, 50); // sets a slight delay and then restores normal error reporting
window.onerror = function(message, url, lineNumber) {
return true;
};
throw new Error('controlledError');
Define a variable inside the JavaScript function, set this variable to 1 if you want ot execute the function and set it to 0 if you want to stop it
var execute;
function do_something()
{
if (execute == 1)
{
// execute your function
}
else
{
// do nothing
}
}
The process is tedious, but in Firefox:
Open a blank tab/window to create a new environment for the script
from the current page
Populate that new environment with the script to execute
Activate the script in the new environment
Close (that is, kill) that new environment to ...
stop or terminate JavaScript this [in a] way to [that it] prevent[s] any further
JavaScript-based execution from occuring, without reloading the browser
Notes:
Step 4 only stops execution of JavaScript in that environment and not the scripts of any other windows
The original page is not reloaded but a new tab/window is loaded with the script
When a tab/window is closed, everything in that environment is gone: all remnants, partial results, code, etc.
Results must migrate back to the parent or another window for preservation
To rerun the code, the above steps must be repeated
Other browsers have and use different conventions.