sabell2012
Mega Sage
Mega Sage

NOTE: MY POSTINGS REFLECT MY OWN VIEWS AND DO NOT NECESSARILY REPRESENT THE VIEWS OF MY EMPLOYER, ACCENTURE.

 

DIFFICULTY LEVEL:    ADVANCED
Assumes having taken the class SSNF and has good advanced level of knowledge and/or familiarity with Scripting in ServiceNow. Assumes good knowledge and/or familiarity of Orchestration, Workflows, and Scripting in ServiceNow.


From time-to-time I create a Custom PowerShell Activity, and usually everything is hunky dory with implementation and execution. However, once-in-awhile my perfect world is shattered when an error occurs in my custom activity! Not in the actual PowerShell script, but perhaps, gasp, I made an error in the pre-processing script. This would cause the Activity to fail prior to running the post-processing script; where I would normally handle errors coming back from the PowerShell script.

 

The result? Everything gets bypassed, and if you do it right your conditions include an "else" branch and you have a partially controlled exit. Now for the bad part: The errors show up in the workflow context logs, but they are not available in the data bus stream!  You can't get at them through either the context or activity objects. So, basically you are forced to hard code a Run Script Activity to deal with the problem. Very unsatisfactory. If we could just have those Workflow Context logs in the data bus!!! Well, guess what? You can!

 

Pre-Requisites

 

 

Lab 1.1:  Create a Test Error Custom PowerShell Activity and Then Pull the Workflow Context Logs into the Data Bus Stream

Don't you just love long titles? 😁

 

Create the Workflow

 

1. On your personal instance navigate to Orchestration > Workflow Editor. The Workflow Editor will be displayed.

2. From the Workflow tab click on the plus ("+") icon to create a new workflow.

3. Fill out the New Workflow form with the following:

Name: Grabbing the Context Logs

Table: Global

Description: Example of how to pull the current context logs into the current workflow

4. Click on the Submit button to save the new workflow.

 

Create the New Custom Activity

1. Navigate to the Custom tab and click on the plus ("+") icon. Choose PowerShell.

2. On the General Tab fill in the form with the following:

Name: Test Error Activity

Short Description: Throw an error in the preview script

Accessible From: All Application Scopes

Category: PowerShell

Description: Throw an error from the Activity level

 

sabell2012_0-1703963886160.png

 

3. Click on the Continue button.

4. From the Inputs tab click on the Go to Pre-Processing button (there will be no inputs for this activity).

5. Fill in the Pre-Processing form with the following:

Input process script: 

throw 'something bad happened';

 

sabell2012_1-1703963937430.png

 

6. Click on the Continue button.

7. From the Execution Command tab click on the Continue button. We won't be doing anything here either.

8. From the Outputs tab add a new Output variable

Name: result

Type: String

 

sabell2012_2-1703964004136.png

 

9. Click on the Go To Post Processing button.

10. Fill in the Post Processing form with the following:

Output process script

activityOutput.result = 'success';

 

sabell2012_3-1703964034854.png

 

11. Click on the Continue button.

12. Add two new Conditions.

Name: Success

Condition:

activityOutput.result == 'success'

Order: 100

 

Name: Failure

Else: true

Order: 200

 

sabell2012_4-1703964103284.png

 

13. Click on the Save button.

14. Go back to your new Workflow and drag out the new Test Error Activity onto the canvas between Begin and End.

Name: Test Activity Failure

15. Click on the Submit button.

16. Add a new Run Script Activity:

Name: Handle Success

Script

 

var location = context.name + '.' + activity.name;
gs.info('---> [{0}] Success!!!', [location]);

 

17. Click on the Save button to save the activity.

18. Add another Run Script Activity:

Name: Retrieve WF Context Logs

Script:

 

// This is where our context logs are kept
// We use the context object in our running workflow to retrieve these logs
// Make sure you grab errors (we could pull in everything is we so choose)
var wfContextLogs = new GlideRecord('wf_log');
wfContextLogs.addQuery('context', context.sys_id);
wfContextLogs.addQuery('level', '2'); // errors

// we may not care about these if they occur
//wfContextLogs.addQuery('message','NOT LIKE','%ReferenceError%'); 

// Order by most recent descending
wfContextLogs.orderByDesc('sys_update_on');
wfContextLogs.query();

// Print them out into the System log to view them
message = '';
while (wfContextLogs.next()) {
	message += wfContextLogs.message + '\n';
}
gs.info('---> Context logs:\n' + message + '');

// now push the errors out onto the data stream!
workflow.scratchpad.context_errors = message;

 

19. Click on the Save button to save the activity.

20. Wire up your workflow to look like the following:

 

sabell2012_5-1703964420493.png

 

 

Testing the Workflow

 

1. Now click on the Run Workflow button, and observe that the context logs are actually printed out on the System Log.

a. The new Custom Activity blows up inside the activity (important).

 

sabell2012_6-1703964506196.png

 

b. The failure pipe handles the error.

c. The Retrieve WF Context Logs Run Script activity does just that, then prints out the errors in the System Log, then puts those logs into the worflow.scratchpad variable ostensibly for future use.

 

Note the error: Wrapped ReferenceError: "activityOutput" is not defined... . This is because the Custom Activity exploded before it had a chance to internally define the object. When the Post Processing code was then executed it caused this error. The Condition captures the "Else" and you are safe then to handle the error(s) gracefully.

 

Your results should look something like this in the System logs:

 

sabell2012_7-1703964584511.png

 

And there you go! I really wish these errors existed inside of an object in the data stream, but this is a good alternative to that lack.

 

Enjoy!

Steven Bell.

 

If you find this article helps you, don't forget to log in and mark it as "Helpful"!

 

sabell2012_0-1703895526613.png


Originally published on: 07-26-2018 10:49 AM

I updated the code, fixed broken links, and brought the article into alignment with my new formatting standard.

Comments
VaranAwesomenow
Mega Sage

Dear Steve,

 

The link in the signature doesnt take to any valid page.

 

sabell2012
Mega Sage
Mega Sage

Thanks, wasn't aware of that. Fixed!

Steven.

DanielCordick
Mega Patron
Mega Patron

how can you get the custom activity to internally define the object before it explodes?

blairedanny
Tera Guru

I realize this post is quite old, but I have the same question as Danny, how can we define activityOutput before it creates the error?  We want to proactively clean up our error logs, but see this one more than we'd like to.  In my mind, I would have thought the system itself would define activityOutput when the activity starts, but looks like that isn't the case.  HI is no help with this either!

Any information is greatly appreciated.  Thanks.

Blaire

Version history
Last update:
‎12-30-2023 11:30 AM
Updated by:
Contributors