ServiceNow Clean Up: Clear system logs from meaningless JAVA exceptions

It is mandatory to monitor ServiceNow system errors and warnings to ensure your instance has up to date fixes ready before issues a brought over via incidents. However, not all system logs are meaningful and some of them can be ignored or hidden.

To hide any JAVA exceptions that have no meaning to SN customers you can create a system property:

Name: glide.client_abort_exception_names

Type: CSV string

Value example: org.apache.catalina.core.AsyncContextImpl.dispatch,RrdException,com.glideapp.report_charting_v2.exceptions.ChartDataGenException

Note: primary reason to disable exception logs, rather than hiding via filters is because not all logs can be hidden and there is a limit how many filter conditions you can have. Also report performance is increased significantly as well.

Warning: you must be well aware of the issue that generated the log and only then decide to hide it, otherwise serious issues might be left unnoticed.

This should be reviewed after every upgrade as well to ensure exceptions are still relevant and have not been removed by SN or other issues with same exception were introduced.

NOW Experience: how to open a New Tab via dispatch

You can open new tab in Agent Workspace in 2 ways: 1) Via component; 2) Via Client Script.

UI Component

Component does not require any dependencies. The action name to open a new record (new tab) is called ‘REFERENCE_INFO_CLICK’. If we create a component and put it in the contextual side panel, when the button is clicked, it will open a new tab with provided details, or if the tab is open it will switch to the tab itself. This component can be used anywhere in AW, not just side panel.

import { createCustomElement } from '@servicenow/ui-core';
import snabbdom from '@servicenow/ui-renderer-snabbdom';

const REFERENCE_INFO_CLICK = 'REFERENCE_INFO_CLICK';

const view = (state, { updateState, dispatch }) => {
    return (
        <div>
            <button on-click={
                () => {
                    dispatch(REFERENCE_INFO_CLICK, {
                        "referenceInfoClick": {
                            // Table of record you want to open
                            "referencetable": "sys_user", 

                            // Record you want to open sys_id
			    "sys_id": "6816f79cc0a8016401c5a33be04be441" 
			}
		    });
                }
            }> Open New Tab</button>
        </div>
    );
};

createCustomElement('x-177418-dispatch-new-tab', {
    renderer: { type: snabbdom },
    view,
});

Client Script

You have to use GlideAgentWorkspace (g_aw) API. This one is fully documented here. For example:

g_aw.openRecord("sys_user", "6816f79cc0a8016401c5a33be04be441");

You can see in the source code g_aw.openRecord actually uses PREVIEW_RECORD dispatch which can be used in the component like this as well:

NOW Experience: HTTP Effect Cheat Sheet

Http Effect is currently the single official method to communicate to ServiceNow server via REST API’s using Seismic UI framework.

Note: information is up to date as of latest Orlando release.

To install it:

npm install @servicenow/ui-effect-http

Import it to your js file:

import { createHttpEffect } from '@servicenow/ui-effect-http';

URL, Method and Headers option

They are typical REST API endpoints and options that can be found via REST API explorer, docs or by navigating SN pages and inspecting chrome developer tools network tab.

Batch option

With batch you define and use same REST API endpoints, but they get converted to /api/now/v1/batch endpoint with encoded request and response payloads.

Batching is set to true by default, batching comes with performance improvement in certain cases when 2 or more API calls are required. Batching single API call has worse performance than not using batch. Batching too many API calls together might have worse end user experience if users can be presented with something first, rather than everything at once. Encoded payload makes payload debugging harder.

encodeURIComponent option

Encodes the call with percent encoding removing all non-alpha numerical characters (# becomes %23 for example). Should be left default at true.

dataParam option

This is used to build Request Payload (body), usually for POST calls. Second parameter of dispatch function holds single JSON object for the Call parameters. In this case object name is data and in the Effect it is defined as ‘data’ string. Only the names should match, it could be called anything. Below will create a user with provided details.

Action:

dispatch(USER_CREATED, {
    data: { "active": "true", "user_name": "E1325", "first_name": "John", "last_name": "Doe" }
});

Action handler:

USER_CREATED: createUserEffect,

Effect:

const createUserEffect = createHttpEffect('/api/now/table/sys_user', {
    method: 'POST',
    dataParam: 'data',
});

pathParams option

Second parameter of dispatch function holds JSON object for the Call parameters that are in pairs. URL maps to JSON object by putting : in front of object name.

Action:

dispatch(USER_FETCHED_QUERY_PARAMS, {
    table: 'sys_user',
    sysparm_query: 'active=true',
    sysparm_limit: 10
})

Action handler:

USER_FETCHED: fetchUsersEffect,

Effect:

const fetchUsersEffect = createHttpEffect('/api/now/table/:table', {
    batch: false,
    method: 'GET',
    pathParams: ['table'],
    queryParams: [
        'sysparm_query',
        'sysparm_limit'
    ],
    successActionType: USER_FETCH_SUCCESS,
});

Note: you can mix pathParams with queryParams within single Effect, however you cannot mix dataParams option.

queryParams option

This option looks similar to REST API Explorer in SN options. It holds a JSON object with and maps exactly.

Action:

dispatch(USER_FETCHED, {
    "id": "E1324", "first_name": "Abel"
});

Action handler:

USER_FETCHED: fetchUsersEffectQueryParams,

Effect:

const fetchUsersEffectQueryParams = createHttpEffect('/api/now/table/sys_user?sysparm_query=user_name=:id^ORfirst_nameLIKE:first_name', {
    method: 'GET',
    queryParams: ['id', 'first_name']
});

startActionType

Gets triggered right at the start of API call execution.

progressActionType

Used when on progress event is triggered by API call, useful when uploading large attachments to give feedback about upload state. Hovewer, this does not seem possible with current state of HTTPEffect, so I have not found any actual uses yet. Would be interested to hear other experiences.

successActionType

Gets triggered right when API call is done successfully.

errorActionType

Gets triggered right when API call is completed with failure.

Action Type handling:

Coeffects variable holds everything that is available for the action handler. In below case ‘result’ variable will hold the response payload (this is same as coeffects.action.payload.result). Response headers are not available yet.

UpdateState will update the initialState with the result payload:

USER_FETCH_SUCCESS: (coeffects) => {
    const {action: {payload: {result}} } = coeffects;

    for (var a in result) {
        coeffects.updateState({
            path: 'records.users',
            value: result[a],
            operation: 'push'
        });
    }
}