I have the following code where I am using VAST player to play my ads.
I am using a check to see if the user has clicked already to avoid the DOM exception that is present in modern browsers.
(function(VASTPlayer) {
'use strict';
var player = new VASTPlayer(document.getElementById(playerID));
player.once('AdStopped', function() {
console.log('Ad finished playback! ' + playerID);
interstitialInstance.close();
});
player.load( << Ad Tag >> ).then(function startAd() {
console.log(player.adDuration + " " + playerID);
var s = document.getElementById(playerID).childNodes[0];
if (s) {
if (!ryads.mouseClick) {
s.muted = true;
} else
s.muted = false;
} else {
console.log("Error while fetching video element!!!");
}
return player.startAd();
}).catch(function(reason) {
console.log('Ad failed to play ' + playerID);
interstitialInstance.close();
setTimeout(function() {
throw reason;
}, 0);
});
}(window.VASTPlayer));
I am getting the following error when I run the Compress job in Jenkins.
project.js:891: ERROR - Parse error. missing name after . operator
}).catch(function(reason) {
^
project.js:892: ERROR - Parse error. syntax error
console.log('Ad failed to play '+playerID);
^
project.js:896: ERROR - Parse error. missing ; before statement
}(window.VASTPlayer));
This is a well known issue since years for yuicompressor.
An easy fix for is to extract the resolve and reject functions of the promise like this:
promise.then(successFunction, failureFunction);
function successFunction() {
console.log('success');
}
function failureFunction(err) {
console.error(err);
}
Replace this line
(function(VASTPlayer) {
by
;(function(VASTPlayer) {
Otherwise, when the compression job is trying to concatenate files, your IIFE might be considered an argument to the code that the end of the file contained which was concatenated right before this file.
Can you please elaborate on what
player.load( << Ad Tag >>
is? That is not valid Javascript. Some sort of JSX dialect? Or just a copy/paste error?
Related
I'm tyring to build and minify my JS using grunt, When i build i didn't get any errors but while minifying i'm getting an error like
../source/js/browse-container.js
1013 | var cards = listCards;
^ 'listCards' is not defined.
>> 1 error in 1 file
Warning: Task "jshint:all" failed. Use --force to continue.
Aborted due to warnings.
Below is the code,I don't see any errors in console, i just get that above error while trying to minify. (Minification is done using uglify)
Please let me know what i'm doing wrong ?
fetchListStatic: function(){
var cards = listCards;
return new Promise(function (resolve) {
if (typeof (cards) !== 'undefined') {
//var cards = listCards;
resolve(cards);
} else {
resolve([]);
}
});
},
I've declared the listCards globally. Hence resolved my issue
var moment, hbs, promise, listCards;
function BrowseContainer() {
}
When a piece of javascript code gives an error in the console. How can I do something like: If this piece of code gives back an error execute another piece of code?
This is what I have:
try {
var operator = <?=$this->shopRequest[operator]?>;
} catch(errorObj) {
var operator = sessionStorage.getItem('operator');
}
This is the error I get in the console:
Uncaught SyntaxError: Unexpected token ;
Try:
var operator = "<?=$this->shopRequest[operator]?>";
alert(operator);
Edit
of better:
var operator = "<?=str_replace('"', '\"', $this->shopRequest[operator])?>";
just in case it will contain " symbols
If I understood correctly your answer you should use
try {
// your code
} catch(e) {
console.err('Ops ' + e);
// execute here other code
}
You can do something like this:
try
{
// Run some code here
}
catch(err)
{
// Handle errors here; You can make a call to the other piece of code from here
}
I've written an AngularJS app but it's proving a bit of a nightmare to debug. I'm using Grunt + uglify to concatenate and minify my application code. It also creates a source map alongside the minified JS file.
The source map seems to work properly when there is a JS error in the file, but outside of the AngularJS application. e.g. If I write console.log('a.b'); at the top of one of the files, the error logged in the Chrome debugger displays line + file info for the original file, not the minified one.
The problem occurs when there is a problem with code that Angular runs itself (e.g. in Controller code). I get a nice stack trace from Angular, but it only details the minified file not the original.
Is there anything I can do to get Angular to acknowledge the source map?
Example error below:
TypeError: Cannot call method 'getElement' of undefined
at Object.addMapControls (http://my-site/wp-content/plugins/my-maps/assets/js/app.min.js:1:2848)
at Object.g [as init] (http://my-site/wp-content/plugins/my-maps/assets/js/app.min.js:1:344)
at new a (http://my-site/wp-content/plugins/my-maps/assets/js/app.min.js:1:591)
at d (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.min.js:29:495)
at Object.instantiate (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.2/angular.min.js:30:123)
Larrifax's answer is good but there is an improved version of the function documented in the same issue report:
.config(function($provide) {
// Fix sourcemaps
// #url https://github.com/angular/angular.js/issues/5217#issuecomment-50993513
$provide.decorator('$exceptionHandler', function($delegate) {
return function(exception, cause) {
$delegate(exception, cause);
setTimeout(function() {
throw exception;
});
};
});
})
This will generate two stack traces, as Andrew Magee noted: one formatted by Angular, then a second one formatted by the browser. The second trace will apply sourcemaps. It's probably not a great idea to disable the duplicates, because you may have other Angular modules that also do work with exceptions that could be called after this via the delegation.
The only solution I could find is to bite the bullet and parse the source maps yourself. Here is some code that will do this. First you need to add source-map to your page. Then add this code:
angular.module('Shared').factory('$exceptionHandler',
function($log, $window, $injector) {
var getSourceMappedStackTrace = function(exception) {
var $q = $injector.get('$q'),
$http = $injector.get('$http'),
SMConsumer = window.sourceMap.SourceMapConsumer,
cache = {};
// Retrieve a SourceMap object for a minified script URL
var getMapForScript = function(url) {
if (cache[url]) {
return cache[url];
} else {
var promise = $http.get(url).then(function(response) {
var m = response.data.match(/\/\/# sourceMappingURL=(.+\.map)/);
if (m) {
var path = url.match(/^(.+)\/[^/]+$/);
path = path && path[1];
return $http.get(path + '/' + m[1]).then(function(response) {
return new SMConsumer(response.data);
});
} else {
return $q.reject();
}
});
cache[url] = promise;
return promise;
}
};
if (exception.stack) { // not all browsers support stack traces
return $q.all(_.map(exception.stack.split(/\n/), function(stackLine) {
var match = stackLine.match(/^(.+)(http.+):(\d+):(\d+)/);
if (match) {
var prefix = match[1], url = match[2], line = match[3], col = match[4];
return getMapForScript(url).then(function(map) {
var pos = map.originalPositionFor({
line: parseInt(line, 10),
column: parseInt(col, 10)
});
var mangledName = prefix.match(/\s*(at)?\s*(.*?)\s*(\(|#)/);
mangledName = (mangledName && mangledName[2]) || '';
return ' at ' + (pos.name ? pos.name : mangledName) + ' ' +
$window.location.origin + pos.source + ':' + pos.line + ':' +
pos.column;
}, function() {
return stackLine;
});
} else {
return $q.when(stackLine);
}
})).then(function (lines) {
return lines.join('\n');
});
} else {
return $q.when('');
}
};
return function(exception) {
getSourceMappedStackTrace(exception).then($log.error);
};
});
This code will download the source, then download the sourcemaps, parse them, and finally attempt to replace the locations in the stack trace the mapped locations. This works perfectly in Chrome, and quite acceptably in Firefox. The disadvantage is that you are adding a fairly large dependency to your code base and that you move from very fast synchronous error reporting to fairly slow async error reporting.
I just had the same issue and have been hunting around for a solution - apparently it's a Chrome issue with stack traces in general and happens to apply to Angular because it uses stack traces in error reporting. See:
Will the source mapping in Google Chrome push to Error.stack
I would take a look at the following project: https://github.com/novocaine/sourcemapped-stacktrace
It does essentially the same thing as the answer from #jakub-hampl but might be useful.
According to this issue it seems that Angular's $logProvider breaks sourcemapping. A workaround like this is suggested in the issue:
var module = angular.module('source-map-exception-handler', [])
module.config(function($provide) {
$provide.decorator('$exceptionHandler', function($delegate) {
return function(exception, cause) {
$delegate(exception, cause);
throw exception;
};
});
});
As the bug has been fixed in Chrome (but the issue persists in Angular), a workaround that doesn’t print out the stack trace twice would be this:
app.factory('$exceptionHandler', function() {
return function(exception, cause) {
console.error(exception.stack);
};
});
When I load the page in my browser, the page gets served correctly. When the javascript executes, Chrome's console output says:
Invalid UTF-8 sequence in header value
I have searched for that string, and am unable to find any mention of it for golang.
How do I go about telling golang not to write unicode characters to web sockets?
I assume that this is the cause of the problem, as the "Network" tab only reveals an empty request and response for this.
CCSSE:
main.go:
package main
import (
"fmt"
"net/http"
"log"
"code.google.com/p/go.net/websocket"
//"github.com/garyburd/go-websocket/websocket"
)
const listenAddress = "localhost:9999"
func wsHandler(webSck *websocket.Conn) {
fmt.Fprint(webSck, "Rpy")
fmt.Println("Sent \"Rpy\" to web socket", webSck)
//more code here
}
func main() {
http.Handle("/", http.FileServer(http.Dir("./static")))
http.Handle("/ws", websocket.Handler(wsHandler))
err := http.ListenAndServe(listenAddress, nil)
if err != nil {
log.Fatal(err)
}
}
static/main.js
var socket = new WebSocket("ws://localhost:9999/ws");
socket.onopen = function() {
socket.onmessage = function(m) {
console.log("Received: " + m);
};
socket.send("Req\n");
};
EDIT:
As suggested by #Intermernet, I have set the Sec-WebSocket-Protocol header. To no avail, still getting Invalid UTF-8 sequence in header value.
Note also that the reason I need to do webSck.Config().Header = make(http.Header) is that it is nil - confirmed by the log statement on webSck.Config(). Tack on to this another question - why do I have to do this; is there an intialisation step that I have missed somewhere?
func wsHandler(webSck *websocket.Conn) {
webSck.Config().Header = make(http.Header)
webSck.Config().Header.Add("Sec-WebSocket-Protocol", "chat")
fmt.Printf("ws.Config() %#v\n", webSck.Config())
var buf []byte;
buf = []byte("Rpy")
_, err := webSck.Write(buf)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Printf("Sent \"Rpy\" to web socket %#v\n", webSck)
}
}
Can this issue be related to recent change in code.google.com/p/go.net/websocket ?
https://code.google.com/p/go/source/detail?r=1e65ca1b2499c473ec267ca1d6759b3dc920a599&repo=net
Sorry for the comment in the form of an answer, I can't comment yet...
Are you setting Sec-WebSocket-Protocol header on the websocket Config? (https://code.google.com/p/go/source/browse/websocket/websocket.go?repo=net#74 and https://www.rfc-editor.org/rfc/rfc6455#page-59)
That error message seems to crop up on Google many times relating to incompatibility or conflict with that header.
Something like:
func wsHandler(webSck *websocket.Conn) {
webSck.Config.Header.Add("Sec-WebSocket-Protocol", "chat")
fmt.Fprint(webSck, "Rpy")
fmt.Println("Sent \"Rpy\" to web socket", webSck)
//more code here
}
Also, I think it's preferred to use the Write function on the websocket (https://code.google.com/p/go/source/browse/websocket/websocket.go?repo=net#205) as it encapsulates/converts the written data into frames.
So more like:
func wsHandler(webSck *websocket.Conn) {
webSck.Config.Header.Add("Sec-WebSocket-Protocol", "chat")
_, _ = webSck.Write("Rpy")
fmt.Println("Sent \"Rpy\" to web socket")
//more code here
}
But obviously checking the error from Write!
Hope that helps.
EDIT: Remove the extraneous ", webSck" from the fmt.Println .
I'm building something that includes javascripts on the fly asynchronously, which works, but I'm looking to improve upon the error detection (so all the errors don't just appear to come from some line near the AJAX call that pulls them down.
If I'm using eval to evaluate a multiline javascript file, is there any way to trace which line an error occurs on?
By keeping references to the variables I need when including, I have no problem determining which file the errors occurs in. My problem is determining which line the error occurs in.
Example:
try {
eval("var valid_statement = 7; \n invalid_statement())))");
} catch(e) {
var err = new Error();
err.message = 'Error in Evald Script: ' + e.message;
err.lineNumber = ???
throw err;
}
How can I tell that the error occurred in the second line there?
Specifically I'm interested in doing this in Firefox.
I know that error objects have e.stack in Mozilla browsers, but the output doesn't seem to take into account newlines properly.
The line number in an evaled script starts from the one the eval is on.
An error object has a line number of the line it was created on.
So something like...
try {
eval('var valid_statement = 7; \n invalid_statement())))');
} catch(e) {
var err = e.constructor('Error in Evaled Script: ' + e.message);
// +3 because `err` has the line number of the `eval` line plus two.
err.lineNumber = e.lineNumber - err.lineNumber + 3;
throw err;
}
The global error event-listener will catch the exception from eval and shows the correct line numbers (maybe not in all browsers):
window.addEventListener('error', function(e) {
console.log(e.message
, '\n', e.filename, ':', e.lineno, (e.colno ? ':' + e.colno : '')
, e.error && e.error.stack ? '\n' : '', e.error ? e.error.stack : undefined
);
}, false);
I don't think you can do it with eval reliably. However, you can do this instead of eval:
try {
$("<script />").html(scriptSource).appendTo("head").remove();
} catch (e) {
alert(e.lineNumber);
}
Join the window.addEventListener('error', ...) with document.createElement('script') works for me:
window.addEventListener('error', function(e) {
console.log('Error line:', e.lineno)
}, false);
function runCode (code) {
let js = document.createElement('script')
try {
js.innerHTML = code
document.head.appendChild(js)
}
catch(e) {
// ...
}
document.head.removeChild(js)
}
runCode('// try this:\n1ss') // prints 'Error line: 2'
Thanks to #frederic-leitenberger and #fromin for the solutions parts.