cancel
Showing results for 
Search instead for 
Did you mean: 
JeremyFriedel
Sisense Team Member
Sisense Team Member

Debugging Server Side External Sisense Plugins using HTTP Requests

Sisense external plugins are server-side Sisense plugins that run on the Sisense server itself, rather than in the client-side browser like standard non-external Sisense plugins. These external plugins are stored in the "external-plugins" folder within the Sisense server file structure and are written in standard JavaScript. While most Sisense plugins can be developed using client-side JavaScript, there are cases where server-side code is necessary.

When developing or debugging existing external Sisense plugins, it can be helpful to monitor the status of plugin variables at various points in the code. This can aid in understanding the current behavior or diagnosing errors.

One way to achieve this type of debugging is to send HTTP requests containing the current variable state from the Sisense server. These requests contain the current value of one or more variables at a specific point in the plugin code. The target for these requests can either be a self-hosted server or a cloud-hosted HTTP logging service, such as Webhook.site, which provides a custom URL for logging and viewing HTTP requests through a browser.

Any standard JavaScript HTTP request library can be used. For example, Axios can be used to log the current state of a variable using code like this:

 

 

const debugHTTPRequestFunction = (variableToDebug) => {
    axios.post('https://webhook.site/your-Unique-Webhook-URL-or-any-server-with-viewable-logs', {
        data: [args]
    })
}

 

 

One common issue when sending Sisense JS API objects such as the prism object, or a dashboard or widget object in the payload of a HTTP request, is that the object can be self-referential, making it challenging to convert to JSON in the usual manner. The following code can be used to remove circular references in JSON:

 

 

function refReplacer() {
    let m = new Map(), v = new Map(), init = null;

    return function (field, value) {
        let p = m.get(this) + (Array.isArray(this) ? `[${field}]` : '.' + field);
        let isComplex = value === Object(value)

        if (isComplex) m.set(value, p);

        let pp = v.get(value) || '';
        let path = p.replace(/undefined\.\.?/, '');
        let val = pp ? `#REF:${pp[0] == '[' ? '$' : '$.'}${pp}` : value;

        !init ? (init = value) : (val === init ? val = "#REF:$" : 0);
        if (!pp && isComplex) v.set(value, path);

        return val;
    }
}

 

 

To convert the JSON form of an object with circular references removed back into the object's original state, you can use the following function:

 

 

function parseRefJSON(json) {
    let objToPath = new Map();
    let pathToObj = new Map();
    let o = JSON.parse(json);
    
    let traverse = (parent, field) => {
      let obj = parent;
      let path = '#REF:$';
  
      if (field !== undefined) {
        obj = parent[field];
        path = objToPath.get(parent) + (Array.isArray(parent) ? `[${field}]` : `${field?'.'+field:''}`);
      }
  
      objToPath.set(obj, path);
      pathToObj.set(path, obj);
      
      let ref = pathToObj.get(obj);
      if (ref) parent[field] = ref;
  
      for (let f in obj) if (obj === Object(obj)) traverse(obj, f);
    }
    
    traverse(o);
    return o;
  }

 

 

Below is an example of sending a variable with circular references removed:

 

 

const debugHTTPRequestFunction = (variableToDebug) => {
    axios.post('https://webhook.site/c25d8caa-4cc7-4876-b595-33625c449a45', {
        data: [JSON.parse(JSON.stringify(args, refReplacer())) ]
    })
}

 

 

You can define this function once and use it in multiple parts of your code for debugging.

Another example, incorporating the functions mentioned above, is shown below, where jQuery Ajax functionality is used, and circular references to a Sisense dashboard variable are removed:

 

 

let debugVariable = [JSON.parse(JSON.stringify(prism.activeDashboard, refReplacer()))]

$.ajax({
    type: "POST",
    url: "https://webhook.site/your-Unique-Webhook-URL-or-any-server-with-viewable-logs",
    crossDomain: true,
    data: JSON.stringify({ debugVariable: debugVariable }),
    success: function (data) {
    },
    error: function (err) {
    }
});

 

 

webhooks.png

 

Comment your experience with this, we'd love to start this discussion! 

Rate this article:
Version history
Last update:
‎10-27-2023 11:23 AM
Updated by: