Dash.js - Trapping 404 errors from MPEG-DASH player - javascript

I've using the Dash.js player to play MPEG-DASH videos. The videos are pulled from a server. Every now and then there will be 404 errors due to server issues, I would like to retry the stream in the background by detecting the 404 error and acting accordingly.
The problem is I cannot catch the error, it's thrown from the line
req.send();
Which is in a file called FragmentLoader.js.
I've tried the following error handling:
window.addEventListener('error', function(e) {
console.log("Item: " + e.message);
}, true);
var oReq = new XMLHttpRequest();
oReq.addEventListener("error", function (e) {
console.log("xml item: " + e.message);
}, true);
$(document).ajaxError(function (event, xhr, ajaxOptions, errorThrown) {
alert("ajax erorr");
});
However none of these conditions catch the error. Is there any way to catch these errors thrown from the dash.js player?

Dash.js has internal retry logic on a 404 - it will retry 3 times (so a total of 4 attempts) before giving up. There's some discussion about improving this behaviour further such as trying the other available representations, but that isn't there yet.
However, this depends on the 404 being detected by the page. There are some XHR errors that are completely silent in terms of what JavaScript can see, even though an error is logged to the console on the exact line of req.send(), which is behaviour I've seen here: https://github.com/Dash-Industry-Forum/dash.js/issues/1209
If the request is indeed throwing a 404 that Dash.js' error handling has handled, retried, and then gave up, then you can bind to its error event:
var url = "http://dash.edgesuite.net/envivio/Envivio-dash2/manifest.mpd";
var player = dashjs.MediaPlayer().create();
player.initialize(document.querySelector("#videoPlayer"), url, true);
player.on('error', function(e) {
if (e.error === 'download') {
// dash.js gave up loading something
// e.event.id will tell you what it failed to load (mpd, segment...)
// and e.event.url will have the URL that failed
}
});

its been a bit since i've been in that code, but if memory serves, you should be able to determine it is a 404 by checking the status property of the error
var oReq = new XMLHttpRequest();
oReq.addEventListener("error", function (e) {
console.log("xml item: " + e.status);
}, true);

Related

Fetching error gives more information on error in console than in catch method [duplicate]

I wrote a function that keeps returning an Access-Control-Allow-Origin error. This is actually fine for me; I don't want to fix this. I just want to catch it so I can read its message in my program.
All the code that causes the error to be thrown is within my try block, and my catch block displays the error's string message. However, when I run the code, no error is caught, and the error shows up in red in the console. How do I catch this error and store its message?
try {
var xhr = new XMLHttpRequest();
xhr.onload = function() {
if (this.status < 400 && this.status >= 300) {
console.log('this redirects to ' + this.getResponseHeader("Location"));
} else {
console.log('doesn\'t redirect');
}
}
xhr.open('HEAD', $scope.suggLink, true);
xhr.send();
} catch(e) {
console.log('Caught it!');
console.log(e.message);
}
While browsers will log a more-detailed error message to the console, you can’t access that from your code. See https://bugs.chromium.org/p/chromium/issues/detail?id=118096#c5:
The details of errors of XHRs and Fetch API are not exposed to JavaScript for security reasons.
As far as the what specs actually require here, the Fetch spec is what defines the details of the “status message” to provide in case of an error — even if XHR is used instead of the Fetch API (the XHR spec references the Fetch spec). And for any network error or response blocked by the browser, the Fetch spec requires that the status message be “the empty byte sequence”:
A network error is a response whose status is always 0, status message is always the empty byte sequence, header list is always empty, body is always null, and trailer is always empty.
So all you can get back from any error you can catch is “TypeError: Failed to fetch” or such.
If you’re using XHR, all you have for handling an error is the onerror event handler:
xhr.onerror = function() { console.log("Error occurred but I dunno what exactly.")}
jquery version of above (sideshowbarker's) workaround for CORS error:
let sURL = 'https://www.mocky.io/v2/5185415ba171ea3a00704eed';
$.getJSON(sURL, function (json)
{
console.log('json from web-service ->', json);
})
.fail(function()
{
console.log("error - could not get json data from service");
});

Getting the error text in an XMLHttpRequest error call back

Given this little snippet of code:
function getPage () {
var xhttp = new XMLHttpRequest();
xhttp.addEventListener("error", getFailed);
xhttp.open("GET", "http://nonexistentserver.com", true);
xhttp.send();
}
function getFailed(msg) {
// I get an ProgressEvent object which doesn't have any text properties?
}
When it runs, the getFailed() callback does indeed get called, but I can't find any information on how to determine what the error was. When I searched for information, all I could find were HTML errors (like 404) and bug reports about causing an error. How do I obtain information about what the failure was available in the error callback?
It seems like in your case it's impossible to get the error information. There are some properties which show the request status: XMLHttpRequest.status, XMLHttpRequest.statusText and XMLHttpRequest.responseText. But they all don't work here (only XMLHttpRequest.status shows '0') in this case. Error event of XMLHttpRequest is called when just error occurs. It doesn't send any information about the error. I hope these will help you: XMLHttpRequest and XMLHttpRequest Properties
You can try to use onprogress event and handle the status code, like this:
var xhr = new XMLHttpRequest;
xhr.onprogress = function () {
console.log(xhr.status); //404 will be printed on console
};
xhr.open('GET', '/noexists');
xhr.send();
In the getFailed call:
function getFailed(e) {
console.log('response error:', e.currentTarget.response);
}
The e.currentTarget is the same xhr instance.

Chrome extension - unable to catch javascript error

I am trying to catch all JavaScript errors from a specific website via a chrome extension. I am very inexperienced with javascript and for some odd reason my error handler isnt catching all of the errors, most importantly, the one on line 191 "Load timeout for modules":
https://hastebin.com/atuwiboqec.js
The error "script error" on line 507 comes through just fine.
This is my content.js file that I have under "content_scripts" in the manifest, it runs at document_start:
var script=document.createElement("script");
script.src=chrome.runtime.getURL("myscript.js");
script.async=false;
document.documentElement.appendChild(script);
This is my myscript.js file:
window.addEventListener("error", handleException, false);
window.addEventListener("unhandledrejection", handleException, false);
function handleException(I_sMsg) {
console.log("Error0 occured: " + I_sMsg.message);
return cancelEvent(I_sMsg);
};
window.onerror = function ErrorHandler(errorMsg, url, lineNumber) {
console.log("Error1 occured: " + errorMsg);
return false;
};
window.addEventListener("timeout", function(e) {
console.log("Error2 occured: " + e.error.message);
return false;
});
When the error "script error" occurs, both Error0 and Error1 messages get printed. When the error "load timeout for modules" occurs, nothing happens even though the error shows up as "Uncaught Error: Load timeout for modules" in the chrome console, in red, with log level "error". This indicates that the error is being thrown:
error in console image
How can I catch that error, or even better, all errors from that site?
P.S I am unsure of how to trigger that load timeout error. It only happens every now and then. I believe a slow network is the cause.
EDIT: Updated the url domain to a backup one as it wasnt resolving.

Javascript try-catch doesn't catch 'Failed to load resource: net::ERR_CONNECTION_RESET '

I have a multiple file uploader but while it's uploading sometimes 1 out of 10 files doesn't make it and it returns a Failed to load resource: net::ERR_CONNECTION_RESET in chrome console. I tried to catch it with the try-catch, but it acts as if no error occurred. What am I doing wrong?
var ajax = new XMLHttpRequest();
ajax.open("POST", "/multiFileUploadHandler.php");
try {
ajax.send(formdata);
} catch (err) {
alert('Error: '+err);
}
This is likely because it is async. Try catching this with an onerror event handler.
ajax.onerror = function(error) {
// handle error
};
edit: corrected syntax.

Shouldn't the error event of xmlhttprequest have an error message?

I'm working on making an AJAX request from a Firefox extension. I have this code:
function GetMenu(){
var oReq = Components.classes["#mozilla.org/xmlextras/xmlhttprequest;1"].createInstance();
// Setup event handlers - must be set before calling open()
oReq.addEventListener("progress", updateProgress, false);
oReq.addEventListener("load", transferComplete, false);
oReq.addEventListener("error", transferFailed, false);
oReq.addEventListener("abort", transferCanceled, false);
oReq.open('POST', "http://www.foo.bar/", true);
oReq.send('your=data&and=more&stuff=here');
}
function transferFailed(evt) {
Application.console.log("An error occurred while transferring the file.");
Application.console.log(this.responseText);
for(var i in evt)
Application.console.log(i+ ' => '+evt[i]);
}
The request fails because http://www.foo.bar/ does not exist (I assume). My question is, why is there no error message in the evt object passed to transferFailed() that says, "The domain does not exist" or "DNS failure" or something of that nature? None of the event object's properties have any indication of what the problem is, no message, no error code, etc.
Shouldn't there be some sort of indication of what the actual error is?
Since you're running with chrome-privileges:
function transferFailed(evt) {
if (this.channel && this.channel.status == Components.results.NS_ERROR_UNKNOWN_HOST) {
alert("DNS error");
}
}
(what #paa said in the comment).
See (you might need to QueryInterface/instanceof accordingly):
nsIRequest
nsIChannel
nsIHttpChannel
nsIHttpChannelInternal
Network errors are not propagated to the caller.
status (and statusText, though it's whatever the server likes) is about HTTP.

Categories