Handle errors in your Qlik Sense mashup

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();
 });
Or perhaps, a angular version:
//create an array for errors
$scope.errors = [];
qlik.setOnError(function (error) {
    // TODO:error handling
    console.log('Qlik error', error);
    $scope.errors.push(error);
});
and in your template something like this:
<div ng-repeat="err in errors" class="alert">{{err.message}}</div>
Then just add a button for clearing errors ($scope.errors.length = 0 would do the trick) add some styling and you’ve got a first attempt.

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.",
So there we are, we need to handle also OnSessionClosed and OnSessionTimedOut. This gives us something like this:
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;
     }
});
And that’s it, we now have error handling thats shows error messages to users and sets a flag when the user should refresh. We can then use the flag to for example display a refresh button and/or disable interactivity like selections.

1 comment

Leave a Reply

Your email address will not be published. Required fields are marked *