While error handling in a Qlik Sense mashup is not automatic, and the documentation is not that good, it’s really not that difficult to get it right. But there are a few things you need to know.
Why do you need it?
Your mashup might work perfectly well when you are testing it. All code is verified, all object id’s refer to objects that actually exist in the app, you have solved the problem with appid’s that differ between your development environment and production. Still there are situations where you need your error handling:
- unauthorized users: the Qlik Sense hub makes sure to only show apps the user has access to, but for mashups there is no such mechanism, so it’s up to you to handle this situation. Qlik Sense will not allow the user to actually open the app, but he will probably be able to open the mashup, so you will need to handle the situation where he has no access to the app
- timeout: if your users are inactive, their sessions will be closed. This means that they will not be able to continue (or restart) working in your mashup without reconnecting, most likely by doing a reload of the mashup. You need to tell the user what has happened and what they should do.
Api support
To help you with this is the setOnError method. It allows you to register a function that is called whenever an error occurs. This is both for errors that are the result of a call, like opening an app that does not exist (or the user is not authorized to access), and errors that are generated from the server, like timeouts. Obviously a good start is to display the error.
qlik.setOnError(function (error) { // TODO:error handling console.log('Qlik error', error); $("#errmsg").html(error.message).parent().show(); });
//create an array for errors $scope.errors = []; qlik.setOnError(function (error) { // TODO:error handling console.log('Qlik error', error); $scope.errors.push(error); });
<div ng-repeat="err in errors" class="alert">{{err.message}}</div>
Add some intelligence
But for some errors showing the error is not enough. For example if the user gets a timeout, he needs to refresh before continuing to work. If the user has no access the rest of your mashup will probably be empty (well if you show data from other sources they might be available).
To do this we need to use the error code we get with the message. As far as I know there is no official documentation of Qlik Sense error codes, but if you’ve got Qlik Sense desktop installed, you can easily find one. Just start Qlik Sense Desktop and in your browser go to:
http://localhost:4848/resources/translate/en-US/engine.js
As you might have guessed, this file contains, among other things, error code from QIX Engine. After you formatted this file, you will find something like this in it:
"ErrorCode.-128": "Internal engine error", "ErrorCode.-1": "Unknown error", "ErrorCode.0": "Unknown error", "ErrorCode.1": "Some data is not correctly specified.", "ErrorCode.2": "The resource could not be found.", "ErrorCode.3": "Resource already exists.", "ErrorCode.4": "Invalid path", "ErrorCode.5": "Access is denied", "ErrorCode.6": "The system is out of memory.", "ErrorCode.7": "Not initialized", "ErrorCode.8": "Invalid parameters", "ErrorCode.9": "Some parameters are empty.", "ErrorCode.10": "Internal error", "ErrorCode.11": "Corrupted data", "ErrorCode.12": "Memory inconsistency", "ErrorCode.13": "Action was aborted unexpectedly.", "ErrorCode.14": "Validation cannot be performed at the moment. Please try again later.", "ErrorCode.15": "Operation aborted", "ErrorCode.16": "Connection lost. Make sure that Qlik Sense is running properly. If your session has timed out due to inactivity, refresh to continue working.",
So there it is, error code 16 means connection lost, so if we get that we should encourage the user to refresh, perhaps display a button or something and perhaps even disable stuff that won’t work, like selections etc.
The error code from QIX engine will be in error.code in the object that is the parameter to our error funtion, so we can simply test that:
qlik.setOnError(function (error) { // TODO:error handling console.log('Qlik error', error); $scope.errors.push(error); if(error.code === 16){ $scope.showRefresh = true; } });
Handle proxy errors
But we’re not quite through yet. When you install your mashup on Qlik Sense server, you’ll notice that not all error object have the ‘code’ field. That’s because proxy errors have another format. Instead of the code field, there is a method field. And they’re not in the engine.js file. Instead you need to look in:
http://localhost:4848/resources/translate/en-US/client.js
In it you will find the proxy errors:
"ProxyError.OnEngineWebsocketFailed": "Connection to the Qlik Sense engine failed for unspecified reasons. Refresh your browser or contact your system administrator.", "ProxyError.OnLicenseAccessDenied": "You cannot access Qlik Sense because you have no access pass.", "ProxyError.OnLicenseAccessDeniedPendingUserSync": "Your access pass credentials are being synced. Refresh your browser or contact your system administrator.", "ProxyError.OnNoEngineAvailable": "No available Qlik Sense engine was found. Refresh your browser or contact your system administrator.", "ProxyError.OnSessionClosed": "Your session has been closed. Refresh your browser to continue working.", "ProxyError.OnNoDataPrepServiceAvailable": "Data Profiling service is not available.", "ProxyError.OnDataPrepServiceWebsocketFailed": "Data Profiling service connection failed. Refresh your browser.", "ProxyError.OnSessionTimedOut": "Your session has timed out. Log back in to Qlik Sense to continue.",
qlik.setOnError(function (error) { //error handling console.log('Qlik error', error); $scope.errors.push(error); if(error.code === 16 || ["OnSessionTimedOut","OnSessionClosed"].indexOf(error.method)>-1){ $scope.showRefresh = true; } });
Thanks for this post Erik, very useful!
As of Qlik Sense 2018 February, the setOnError() is deprecated, and we are asked to use app.on(‘closed’, …) or qlik.getGlobal().on(‘closed’, …).
Pulling out my network cable, the app.on(‘closed’, …) returned, while app.on(‘error’, …) remained silent.
The object I received contained event.code == 16, and event.message == “Connection lost. Make sure that Qlik Sense is running properly. If your session has timed out due to inactivity, refresh to continue working.”.
I have not been able to test ProxyError, though. Will the “OnSessionTimedOut”, “OnSessionClosed” trigger app.on(‘closed’, …) as well? Or will they perhaps appear under app.on(‘error’, …)?
Anyone knows?
Cheers 🙂
In which scenarios Error Code is equal to ‘Undefined’ and message is Object Not Found. Please explain
-Thanks
Ramesh