AngularJS $LogProvider throws Illegal access error - javascript

I have a mobile app that uses cordova + AngularJS 1.2.4 It works perfect on every platform I tested except some Android 2.3.X devices throw a mysterious illegal access exception. Below is the portion of code that raises the error. Precisely speaking, the line return logFn.apply(console, args); seems to be the culprit. If I remove the parameter args code works fine. It seems odd since variable args is defined at the top of the function. I don't understand what is really causing this illegal access error? Any one had a similar problem? Any ideas how to fix it?
ps: Please check out inline comments to better understand the problem. There, I debugged and reported some cases.
function consoleLog(type) {
var console = $window.console || {},
logFn = console[type] || console.log || noop;
if (logFn.apply) {
return function() {
var args = [];
forEach(arguments, function(arg) {
args.push(formatError(arg));
// console.log(typeof arg); -> prints string
// console.log(arg.toString); -> prints function
// console.log(arg); -> throws illegal access error
// console.log(arg.toString()); -> throws illegal access error
});
// console.log(args); -> throws illegal access error
// return logFn.apply(console); -> works fine w/o `args`
return logFn.apply(console, args); -> throws illegal access error
};
}
// we are IE which either doesn't have window.console => this is noop and we do nothing,
// or we are IE where console.log doesn't have apply so we log at least first 2 args
return function(arg1, arg2) {
logFn(arg1, arg2 == null ? '' : arg2);
};
}

The code, you posted isn't the problem. This is Angular's built-in Exception handling. I made the same mistake and tried to dig in here, but Angular's Exception Handlings works fine.
But there is a reported Issue (Github) concerning Android 2.3.x and Firefox OS in 1.2.4 and they fixed it in 1.2.5
Maybe you should try a higher AngularJS Version

Related

"catching is not a function" exception

I'm having an issue on JBoss (6.4.14 GA) running jQuery 3.1.1 (or 3.2.1). As soon as a page loads and the documet.ready function executes I get the following error:
jquery.js:formatted:8142 Uncaught TypeError: aj.then(...).catching is not a function
at bw.fn.init.bw.fn.ready (jquery.js:formatted:8142)
at srs.js:1
The jQuery code throwing this error is:
var readyList = jQuery.Deferred();
jQuery.fn.ready = function( fn ) {
readyList
.then( fn )
// Wrap jQuery.readyException in a function so that the lookup
// happens at the time of error handling instead of callback
// registration.
.catching( function( error ) {
jQuery.readyException( error );
} );
return this;
};
I do not get this error when running my application on Tomcat 7.
I've been researching this error for several days and have been unable to find any references to this specific error (catching is not a function), so looking for some help in determining the cause of this error.
Thanks in advance!
catching is not a method of jquery's deferred, you are maybe looking for catch.
For debugging purpose, you can list properties of an object using Object.getOwnPropertyNames and see which one they have. In your case, executing the code below would have helped you find the error:
var debugValue = aj.then(bS)
console.log(Object.getOwnPropertyNames(debugValue))

Is it possible to override console logs

If I receive an error from a framework or an error from the browser. Basically a runtime error of any kind. Without modifying the framework, is it possible for me to override the console logs that these frameworks make and the browser's errors. I want to use my own framework with own error handling system when informing the user of errors of practically anything runtime (not syntax errors). I don't know if you would class it all as runtime errors because of the way javascript is executed in the browser but hopefully you will get me?
Is this possible if all the frameworks are written in Javascript?
How is this achieved?
What considerations do I have to make between different browsers?
Thanks
You are probably looking for a try-catch block:
try {
alert(foo);
} catch(e) {
alert('The code got the following error: '+e.message);
}
Whenever the code between the try {} receives an error, the catch(e) {} block will execute, with the argument e being the error object for the error that occurred. In this case, the variable foo is not defined, so executing this code will result in an alert message saying "The code got the following error: foo is not defined"
While not over-riding console.log, you may be achieve the same effect by overriding window.onerror.
From the MDN documentation
window.onerror = function myErrorHandler(errorMsg, url, lineNumber) {
// Log the error here -- perhaps using an AJAX call
}
You could try overriding the console.log() function.
//Save original reference
var originalConsole = console;
//Override
console = {};
console.log = function()
{
//According to MDN the console.log function can receive a variable number of params
for(var i=0; i<arguments.length; i++)
{
//Make your changes here, then call the original console.log function
originalConsole.log("Change something: "+arguments[i]);
}
//Or maybe do something here after parsing all the arguments
//...
}
console.log("one", "two");
JSFiddle here.
You can override the console logs by creating a "console" object and overriding it's .log() function:
var console = {};
console.log = function(){};
Some browsers require this to be added to the window object directly; so, for browser compatibility, also add:
window.console = console;
Additionally, you can override other console functions (e.g. console.info, console.warn and console.error) if you're using those too.
Also, consider reading this blog post from Udi Talias on overriding the console functions. Good and quick read!
You can custom your console.log here
// copy the original
let originalConsole = Object.assign({}, console);
// do something with your log.
console.log = (value) => {
//some cool condition
if (true) {
value = "new_log : " + value
}
originalConsole.log(value);
};

How can I override/extend ReferenceError in Chrome's JavaScript?

To make debugging easier, I'm capturing all of the console logs in Chrome so that users who submit a feedback entry will also submit all of the logs to our server. When someone encounters a problem in production, I can first and foremost get them back to work so that I can then sit down and more thoroughly go through all of the logs to determine the root cause of whatever issue the user encountered in production.
The technique I use to capture the logs involves overriding console.log so that all text entered in the first argument gets stored in an array while simultaneously invoking the legacy function so that I can still see the logs in the console too.
The problem is when there's the occasional uncaught exception. These aren't included in the uploaded logs, so it's not always clear what caused the problem. So I tried overriding ReferenceError by writing a JavaScript function that takes a function as an argument, then returns a new function that does stuff with it, like storing data in a variable, and then invoking the legacy function as the last step:
function overrideException(legacyFn) {
/** arguments for original fn **/
return function() {
var args = [];
args[0] = arguments[0];
// pass in as arguments to original function and store result to
// prove we overrode the ReferenceError
output = ">> " + legacyFn.apply(this, args).stack;
return legacyFn.apply(this, arguments);
}
}
To test the overrideException function, I ran the following code on the console:
ReferenceError = overrideException(ReferenceError);
Afterwards, I tested the returned function, the new ReferenceError, by manually throwing a ReferenceError:
throw new ReferenceError("YES!! IT WORKS! HAHAHA!");
The resulting output on the console is:
ReferenceError: YES!! IT WORKS! HAHAHA!
And checking the global variable output from the overrideException function shows that it did indeed run:
output
">> ReferenceError: YES!! IT WORKS! HAHAHA!
at ReferenceError (<anonymous>)
at new <anonymous> (<anonymous>:18:35)
at <anonymous>:2:7
at Object.InjectedScript._evaluateOn (<anonymous>:562:39)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:521:52)
at Object.InjectedScript.evaluate (<anonymous>:440:21)"
Now, here's where things start to fall apart. In our code, we're not going to know when an uncaught exception occurs, so I tested it by attempting to run a function that doesn't exist:
ttt();
Which results in:
ReferenceError: ttt is not defined
However, unlike the case where we explicitly throw an error, in this case, the function doesn't fire, and we're left with only the legacy functionality. The contents of the variable output is the same as in the first test.
So the question seems to be this: How do we override the ReferenceError functionality that the JavaScript engine uses to throw errors so that it's the same one we use when we throw a ReferenceError?
Keep in mind that my problem is limited only to Chrome at this time; I'm building a Chrome Packaged app.
I have done quite a bit of research for the same reason: I wanted to log errors and report them.
"Overriding" a native type (whether ReferenceError, String, or Array) is not possible.
Chrome binds these before any Javascript is run, so redefining window.ReferenceError has no effect.
You can extend ReferenceError with something like ReferenceError.prototype.extension = function() { return 0; }, or even override toString (for consistency, try it on the page, not the Dev Tools).
That doesn't help you much.
But not to worry....
(1) Use window.onerror to get file name, 1-indexed line number, and 0-indexed position of uncaught errors, as well as the error itself.
var errorData = [];
onerror = function(message, file, line, position, error) {
errorData.push({message:message, file:file, line:line, position:position, error:error});
};
See the fiddle for an example. Since the OP was Chrome-specific, this has only been tested to work in Chrome.
(2) Because of improvements to (1), this is no longer necessary, but I leave this second technique here for completeness, and since onerror is not guaranteed to work for all errors on all browsers. You will also sometimes see the following:
var errors = [];
function protectedFunction(f) {
return function() {
try {
f.apply(this, arguments);
} catch(e) {
errors.push(e);
throw e;
}
};
}
setTimeout = protectedFunction(setTimeout);
setInterval = protectedFunction(setInterval);
etc...
FYI, all this is very similar to what has been done in the Google Closure Compiler library, in goog.debug, created during Gmail development with the intent of doing exactly this. Of particular interest is goog.debug.ErrorHandler and goog.debug.ErrorReporter.

What is “assert” in JavaScript?

What does assert mean in JavaScript?
I’ve seen something like:
assert(function1() && function2() && function3(), "some text");
And would like to know what the method assert() does.
There is no standard assert in JavaScript itself. Perhaps you're using some library that provides one; for instance, if you're using Node.js, perhaps you're using the assertion module. (Browsers and other environments that offer a console implementing the Console API provide console.assert.)
The usual meaning of an assert function is to throw an error if the expression passed into the function is false; this is part of the general concept of assertion checking. Usually assertions (as they're called) are used only in "testing" or "debug" builds and stripped out of production code.
Suppose you had a function that was supposed to always accept a string. You'd want to know if someone called that function with something that wasn't a string (without having a type checking layer like TypeScript or Flow). So you might do:
assert(typeof argumentName === "string");
...where assert would throw an error if the condition were false.
A very simple version would look like this:
function assert(condition, message) {
if (!condition) {
throw message || "Assertion failed";
}
}
Better yet, make use of the Error object, which has the advantage of collecting a stack trace and such:
function assert(condition, message) {
if (!condition) {
throw new Error(message || "Assertion failed");
}
}
If using a modern browser or nodejs, you can use console.assert(expression, object).
For more information:
Chrome API Reference
Firefox Web Console
Firebug Console API
IE Console API
Opera Dragonfly
Nodejs Console API
The other answers are good: there isn't an assert function built into ECMAScript5 (e.g. JavaScript that works basically everywhere) but some browsers give it to you or have add-ons that provide that functionality. While it's probably best to use a well-established / popular / maintained library for this, for academic purposes a "poor man's assert" function might look something like this:
const assert = function(condition, message) {
if (!condition)
throw Error('Assert failed: ' + (message || ''));
};
assert(1 === 1); // Executes without problem
assert(false, 'Expected true');
// Yields 'Error: Assert failed: Expected true' in console
assert() is not a native javascript function. It is a custom function someone made. You will have to look for it on your page or in your files and post it for anybody to help determine what it's doing.
check this:http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-quick-and-easy-javascript-testing-with-assert/
it is for testing JavaScript. Amazingly, at barely five or six lines, this code provides a great level of power and control over your code, when testing.
The assert function accepts two parameters:
outcome: A boolean, which references whether your test passed or failed
description: A short description of your test.
The assert function then simply creates a list item, applies a class of either “pass” or “fail,” dependent upon whether your test returned true or false, and then appends the description to the list item. Finally, that block of coded is added to the page. It’s crazy simple, but works perfectly.
If the assertion is false, the message is displayed. Specifically, if the first argument is false, the second argument (the string message) will be be logged in the developer tools console. If the first argument is true, basically nothing happens. A simple example – I’m using Google Developer Tools:
var isTrue = true;
var isFalse = false;
console.assert(isTrue, 'Equals true so will NOT log to the console.');
console.assert(isFalse, 'Equals false so WILL log to the console.');
It probably came with a testing library that some of your code is using. Here's an example of one (chances are it's not the same library as your code is using, but it shows the general idea):
http://chaijs.com/guide/styles/#assert
Word or function "assert" is mostly used in testing parts of application.
Assert functions are a short way of instructing the program to check the condition (also called "assertion") and if the condition is not True, it will throw error.
So let's see how it would look like in "normal code"
if (typeof "string" === "array") {
throw Error('Error: "string" !== "array"');
}
With assert you can simply write:
assert(typeof "string" === "array")
In Javascript, there's no native assert function, so you have to use one from some library.
For simple introduction, you can check this article:
http://fredkschott.com/post/2014/05/nodejs-testing-essentials/
I hope it helps.
Assertion throws error message if first attribute is false, and the second attribute is the message to be thrown.
console.assert(condition,message);
There are many comments saying assertion does not exist in JavaScript but console.assert() is the assert function in JavaScript
The idea of assertion is to find why/where the bug occurs.
console.assert(document.getElementById("title"), "You have no element with ID 'title'");
console.assert(document.getElementById("image"), "You have no element with ID 'image'");
Here depending on the message you can find what the bug is.
These error messages will be displayed to console in red color as if we called console.error();
You can use assertions to test your functions eg:
console.assert(myAddFunction(5,8)===(5+8),"Failed on 5 and 8");
Note the condition can be anything like != < > etc
This is commonly used to test if the newly created function works as expected by providing some test cases and is not meant for production.
To see more functions in console execute console.log(console);
In addition to other options like console.assert or rolling your own, you can use invariant. It has a couple of unique features:
It supports formatted error messages (using a %s specifier).
In production environments (as determined by the Node.js or Webpack environment), the error message is optional, allowing for (slightly) smaller .js.
Java has a assert statement, the JVM disables assertion validation by default. They must be explicitly enabled using command line argument -enableassertions (or its shorthand -ea),
while JavaScript supports console.assert(), it's just a logging method and won't interrupt current procedure if assertion failed.
To bring things together and satisfy various needs, here is a tiny js assertion lib.
globalThis.assert = (()=> {
class AssertionError extends Error {
constructor(message) {
super(message);
this.name = 'AssertionError';
}
}
let config = {
async: true,
silent: false
};
function assert(condition, message = undefined) {
if (!condition) {
if (config.silent) {
//NOOP
} else if (config.async) {
console.assert(condition, message || 'assert');
} else {
throw new AssertionError(message || 'assertion failed');
}
}
}
assert.config = config;
return assert;
})();
/* global assert */
Object.assign(assert.config, {
// silent: true, // to disable assertion validation
async: false, // to validate assertion synchronously (will interrupt if assertion failed, like Java's)
});
let items = [
{id: 1},
{id: 2},
{id: 3}
];
function deleteItem(item) {
let index = items.findIndex((e)=> e.id === item.id);
assert(index > -1, `index should be >=0, the item(id=${item.id}) to be deleted doesn't exist, or was already deleted`);
items.splice(index, 1);
}
console.log('begin');
deleteItem({id: 1});
deleteItem({id: 1});
console.log('end');
Node.js has an assert function you can import:
const assert = require('assert')
It works as one would expect, in that assert(false) throws an error, and assert(false, message) throws an error with a message.
The other answers have already pointed out that JS itself has no native assert function, and that remains true as of this writing (April 2021).
Previous answers can be improved in terms of performances and compatibility.
Check once if the Error object exists, if not declare it :
if (typeof Error === "undefined") {
Error = function(message) {
this.message = message;
};
Error.prototype.message = "";
}
Then, each assertion will check the condition, and always throw an Error object
function assert(condition, message) {
if (!condition) throw new Error(message || "Assertion failed");
}
Keep in mind that the console will not display the real error line number, but the line of the assert function, which is not useful for debugging.
If you use webpack, you can just use the node.js assertion library. Although they claim that it's "not intended to be a general purpose assertion library", it seems to be more than OK for ad hoc assertions, and it seems no competitor exists in the Node space anyway (Chai is designed for unit testing).
const assert = require('assert');
...
assert(jqXHR.status == 201, "create response should be 201");
You need to use webpack or browserify to be able to use this, so obviously this is only useful if those are already in your workflow.
As mentioned by T.J., There is no assert in JavaScript.
However, there is a node module named assert, which is used mostly for testing. so, you might see code like:
const assert = require('assert');
assert(5 > 7);
assert() is the assert function in JavaScript. The main idea of assertion is to find why/where the bug occurs.
Chrome devtools support console.assert
You can open devtools and create a snippet in devtools-source-navigator-Snippets. And code some code... and run the snippet...

FullCalendar event on mouseover gives jQuery error

In under the Week-view, on event mouseOver I receive this error message in firebug:
Error: Syntax error, unrecognized expression: ,
throw new Error( "Syntax error, unrecognized expression: " + msg );
jquery-1.8.3.js (line 4680)
has anyone encountered such a problem, or is there a way to debug to origins of the error?
Thanks in advance
Sincerely
It looks like a selector bug:
$("abc, def, "); // or
$("<div,");
Is not sure.
If you look in the source code for jQuery 1.8.3 you will find these lines around line 4680:
/*LINE: 4679*/ Sizzle.error = function( msg ) {
/*LINE: 4680*/ throw new Error( "Syntax error, unrecognized expression: " + msg );
/*LINE: 4681*/ };
It's hard to debug your code from here but you could try to put arguments.callee.caller right before throw new Error:
Sizzle.error = function( msg ) {
console.log( arguments.callee.caller );
throw new Error( "Syntax error, unrecognized expression: " + msg );
};
That will tell you what function is calling this function. From there you can try to travel up using the same method. At the end you will find your problem.
What is arguments.callee.caller?
arguments is an array like property containing all the arguments parsed to a function:
function a() {}
a(1, 2, 3); // Inside a arguments will be: [1, 2, 3]
arguments have a property called callee this property contains a reference to the function called eg. it self:
function a() {} // arguments.callee === a.
arguments.callee have a non standard (but standard, just not described in ECMA) property called caller this property contains a reference to the function who is calling it on runtime.
function a() {
b()
}
function b() {}; // arguments.callee.caller === a;
a();
And some docs:
arguments
arguments.callee
Function.caller
Do you know about the console-object?
The problem was solved by going away from jQuery-Mobile and back to jQuery-UI only.
FullCalendar doesn't work properly under jQuery-Mobile.
The problem was caused by jQuery-Mobile. FullCalendar could not function properly in jQuery-Mobile environment. After going back to jQuery-UI everything worked fine again.
Thanks for your effort to help

Categories