When I loose net connection and try to load a HTML template(which is not loaded previously) using angularJS it gives me error, net::ERR_INTERNET_DISCONNECTED.
Is there any way to call a function before angular fires error net::ERR_INTERNET_DISCONNECTED , so I will be able to notify user they have lost their connection.
I don't want to put watchers on online/offline status since I want user to be able to see previously loaded HTML templates.
From angularjs docs
angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
return function(exception, cause) {
exception.message += ' (caused by "' + cause + '")';
throw exception;
};
});
Use this to catch every exception, including internet connection problems, it all runs through this method
Related
I have Protractor tests that run fine locally (directConnect: true), but when I try to run them on a remote Selenium server (Grid), I always get the following message.
A Jasmine spec timed out. Resetting the WebDriver Control Flow.
Looking at the Failures, the Message and Stack display the following for all my test cases:
Message:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
Stack:
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
at Timer.listOnTimeout (timers.js:92:15)
I've tried a number of things, such as increasing the jasmine timeout interval, adding earlier timeouts such as getPageTimeout and allScriptsTimeout to the conf, but it still throws the jasmine timeout error. The log shows the following error:
00:03:18.328 INFO - Done: [execute async script: try { return (function (rootSelector, ng12Hybrid, callback) {
var el = document.querySelector(rootSelector);
try {
if (!ng12Hybrid && window.getAngularTestability) {
window.getAngularTestability(el).whenStable(callback);
return;
}
if (!window.angular) {
throw new Error('window.angular is undefined. This could be either ' +
'because this is a non-angular page or because your test involves ' +
'client-side navigation, which can interfere with Protractor\'s ' +
'bootstrapping. See http://git.io/v4gXM for details');
}
if (angular.getTestability) {
angular.getTestability(el).whenStable(callback);
} else {
if (!angular.element(el).injector()) {
throw new Error('root element (' + rootSelector + ') has no injector.' +
' this may mean it is not inside ng-app.');
}
angular.element(el).injector().get('$browser').
notifyWhenNoOutstandingRequests(callback);
}
} catch (err) {
callback(err.message);
}
}).apply(this, arguments); }
catch(e) { throw (e instanceof Error) ? e : new Error(e); }, [body, false]])
I know for sure my app is angular and it runs successfully when running locally. I've tried setting
browser.ignoreSynchronization = true
, as well as setting the
rootElement='html#ng-app'
in the conf (bc my ng-app is not in the body, but rather inside the html tag). Framework is set to 'jasmine' although I've tried 'jasmine2' but neither seems to make any difference. On the remote server, I am able to get firefox to start up, and the UI shows me the started firefox session. However it just sits there until the timeout occurs. Any input would be appreciated!
Jasmine needs to know it is running an async process and when that process is supposed to be complete (to proceed with any other test you may be running).
This is obtained by passing done to the Jasmine async method callback and calling done() when the async operation is resolved.
If you don't call done() Jasmine shows a timeout error. I think this should solve your problem.
More info here:
Mocking ngResource in Angular unit tests.
Hope this helps!
I'm using Protractor with Cucumber to write some tests but I'm stuck at some point. In step after login, I'm rerouting to another page using browser.get(url) function provided by protractor. But it always returns before the page is completely loaded. I have tried many solutions so far but no luck. I have tried with browser.wait, browser.get(url).then(function(){ // code when it loads}) but Im getting 0 positive results.
Here's my code:
// Steps will be implemented here
this.Given(/^I am logged in as user \'([^\']*)\'$/, function (user, callback) {
console.log('USER: ' + user);
browser.driver.get('https://cit-was70-l06/ipa')
browser.driver.findElement(by.xpath('my_xpath')).sendKeys(user);
browser.driver.findElement(by.xpath('my_xpath')).sendKeys(user);
browser.driver.findElement(by.xpath('my_xpath')).click().then(callback);
});
this.Then(/^The screen is shown, with title \'([^\']*)\'$/, function (title, callback) {
console.log('Title from feature file: ' + title);
var url = 'some/url/in/application/';
browser.get(url).then(function(){
// This portion executes before page is completely loaded.
// So if I try to get any element, it throws me an error.
// [15:32:13] E/launcher - "process.on('uncaughtException'" error, see
// launcher
// [15:32:13] E/launcher - Process exited with error code 199
// It works if I add static delay to wait for page load completely
// but that will not be a good solution if I have too much pages to test
callback();
});
console.log('After page laoad');
});
Any suggested work around will be much appreciated.
[15:32:13] E/launcher - "process.on('uncaughtException'" error, see launcher
[15:32:13] E/launcher - Process exited with error code 199
The above error can be caused due to various reasons mostly related to promises. But it should throw the correct message. There is already a work around provided here https://github.com/angular/protractor/issues/3384 to catch the exact error message.
You could change the launcher.ts file in your protractor dependency as mentioned in above forum to catch the error inorder to debug your issue.
And I would suggest you to return your promises instead of callbacks when writing step definitions in protractor-cucumber, in this way cucumber would know when to complete its async actions.
Try the below code.check whether it helps.
browser.get(url);
browser.waitForAngular();
then try to call your function.
Use protractor.ExpectedConditions to check visibility of any elements on page which will be displayed after successful login. Write a customized method as shown below.
If element displayed, then navigate other page using browser.get();
Code Snippet
EC = protractor.ExpectedConditions;
//targetElement=element(locator);
this.isElementVisible = function (targetElement, timeOut) {
'use strict';
timeOut = timeOut !== undefined ? timeOut : 8000;
browser.wait(EC.visibilityOf(targetElement),
timeOut).thenCatch(function()
{
assert.fail(' element is not visible');
});
};
I've been trying to setup a timeout value (in milliseconds) for my $resource so that if the server doesn't respond within 10*1000 milliseconds, I want the service in my factory to return the error promise.
I have a factory with the following method:
service.getDelta = $resource(BASE_API_URL + '/delta/:inTable/:inDate',
{inTable: '#inTable', inDate: '#inDate'},
{query: {timeout: 10*1000}});
In the controller I do the following:
getDataPromises.push(remoteService.getDelta.query({inTable: "table1", inDate: clientDateLastModified}).$promise);
getDataPromises.push(remoteService.getDelta.query({inTable: "table2", inDate: clientDateLastModified}).$promise);
getDataPromises.push(remoteService.getDelta.query({inTable: "table3", inDate: clientDateLastModified}).$promise);
getDataPromises.push(remoteService.getDelta.query({inTable: "table4", inDate: clientDateLastModified}).$promise);
Then I check to ensure all are successful or handle error if one fails.
$q.all(getDataPromises).then(
function (result) {
// NOTIFY SUCCESS
},
function (error) {
// NOTIFY ERROR
});
The success in the promise has been coming through as expected. If I leave out the timeout config, I also get the error in the promise for issues like 404. But when I add the timeout, I get the following when I stringify the error object in my error callback:
{"line":13380,"column":32,"sourceURL":"file:///Users/ ... /www/lib/ionic/js/ionic.bundle.js"}
Am I misunderstanding the use of the timeout property?
I am using ionic 1.2.4 which I believe is using Angular 1.4.3.
Note: I know this use case doesn't justify use of $resource and could be done with $http, but I wanted to get to get a feel for using it since I plan to down the road for this app.
Thanks!
I did find a way to handle uncaught exceptions in angularjs by using predefined $exceptionHandler service. According to the doc, I'm delegating exceptions manually by using try {...} - catch(e). See below
try {
$scope.loadImage();
}catch (e){
console.log(e);
}
It is working absolutely fine
But I eager to know how could I handle uncaught exceptions in angular way ? Can anyone please share a working example ?
It is explained in the API.
angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {
return function(exception, cause) {
exception.message += ' (caused by "' + cause + '")';
throw exception;
};
});
This example will override the normal action of
$exceptionHandler, to make angular exceptions fail hard when they
happen, instead of just logging to the console.
Note, that code executed in event-listeners (even those registered
using jqLite's on/bind methods) does not delegate exceptions to the
$exceptionHandler (unless executed during a digest). If you wish,
you can manually delegate exceptions, e.g. try { ... } catch(e) {
$exceptionHandler(e); }
We're using angular translate to handle localization of a web site, using our own custom loader that fetches translations from the server. On the server side, we have logic that handles missing translation keys so that we both return something (a translation from a fallback language or the key itself) and reports to the system that the key was requested (so it shows up in the translation UI elsewhere on the site). Now, I'm struggling with building something similar on the client side.
The $translateProvider has a method useMissingTranslationHandler(factory) which we've successfully configured to just log out that a key is missing to the console, using the following:
app.config(function ($translateProvider) {
$translateProvider.useMissingTranslationHandler('translationMissingHandler');
});
app.factory('translationMissingHandler', translationMissingHandler);
translationMissingHandler.$inject = ['$window', '$log', '$http'];
function translationMissingHandler($window, $log, $http) {
return function (translationId) {
var culture = $window.preferredCulture, // workaround for another problem
errorInfo = {
key: translationId,
culture: culture
};
$log.warning('Translation missing:', errorInfo);
// $http.post('/api/v2/localization/missing', errorInfo);
}
}
However, then I uncomment the POST to the server, notifying about the missing key, the page hangs on line 14394 of angular.js - throw e, where e.message is
[$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: []
I've tried various things to get around this - e.g. wrapping the call to $http.post() in $timeout or $rootScope.$apply but to no avail; I still get the same error message.
Is there a way to schedule a call to $http.post() from here without causing this error? If so, how?