Can anyone please help me troubleshoot? ```{"type"...
# suitescript
k
Can anyone please help me troubleshoot?
Copy code
{
  "type": "error.SuiteScriptError",
  "name": "UNEXPECTED_ERROR",
  "message": null,
  "id": "bef8e13d-64da-4053-b060-9012550c1575-2d323032342e30362e3034",
  "stack": [
    "each(N/searchObject)",
    "getInputData(/SuiteScripts/exportMessagesMR.js:42)"
  ],
  "cause": {
    "type": "internal error",
    "code": "UNEXPECTED_ERROR",
    "details": null,
    "userEvent": null,
    "stackTrace": [
      "each(N/searchObject)",
      "getInputData(/SuiteScripts/exportMessagesMR.js:42)"
    ],
    "notifyOff": false
  },
  "notifyOff": false,
  "userFacing": false
}
a
UNEXPECTED ERROR isn't really troubleshoot-able from the error message
k
Here is the code:
Copy code
log.debug({ title: 'Deployment Search', details: deploymentSearch });
deploymentSearch.run().each(function (result) {
  log.debug({ title: 'Deployment Id: ', details: result.id });
a
that's your getInput function?
k
it's in it
Copy code
function getInputData() {
    try {
      // Get the last run time from the script parameter
      var lastRunTime = runtime.getCurrentScript().getParameter({ name: 'custscript_last_run_time' });
      log.debug({ title: 'Last Run Time', details: lastRunTime });

      // If last run time is null, set it to yesterday at midnight
      if (!lastRunTime) {
        lastRunTime = new Date();
        lastRunTime.setHours(0, 0, 0, 0);
        lastRunTime.setDate(lastRunTime.getDate() - 1);
      }

      // Load the deployment record
      var scriptObj = runtime.getCurrentScript();
      log.debug('Deployment Id: ' + scriptObj.deploymentId); // customdeploy_exportmessages_mr 

      // find the deployment record
      var deploymentSearch = search.create({
        type: "scriptdeployment",
        filters:
          [
            ["scriptid", "is", scriptObj.deploymentId],
            "AND",
            ["script.scriptid", "anyof", scriptObj.id]
          ],
        columns:
          [
            search.createColumn({ name: "script", label: "Script ID" })
          ]
        });
        log.debug({ title: 'Deployment Search', details: deploymentSearch });
        deploymentSearch.run().each(function (result) {
          log.debug({ title: 'Deployment Id: ', details: result.id });
        // load the deployment record
        var deploymentRecord = record.load({
          type: 'scriptdeployment',
          id: result.id
        });
        log.debug({ title: 'Testing after load', details: deploymentRecord.id });
        // set the last run time to now
        deploymentRecord.setValue({
          fieldId: 'custscript_last_run_time',
          value: new Date()
        });
        // save the deployment record
        deploymentRecord.save();
        return false;
      });

      // Search messages created after the last run time, the only column we need is internalid
      var messageSearch = search.create({
        type: 'message',
        filters: [
          ['created', 'after', lastRunTime]
        ],
        columns: ['internalid']
      });

      return messageSearch;
    } catch (e) {
      log.error({
        title: 'Error in getInputData',
        details: e.toString()
      });
    }
  }
The goal is to get all messages since the last runtime
The error occurs at
deploymentSearch.run().each(function (result) {
I don't see anything wrong
a
you're searching for the currently running deployment? after logging it?
why do you need to search for it? you already have its id, you can just load it?
also why are you looping through results, there should only ever be one result right?
k
What shows up in the log is "customdeploy2"
a
its early here, so maybe i'm totally misunderstanding something
k
I need the internal ID to load it
a
right
k
I'm not looping through, I return false
a
.each is a loop, one iteration or not, its weird
k
I use the deployment scriptid and the script internal ID to identify the deployment internal ID
a
anyway, that's not your issue
k
I'd love a more efficient approach
this current one feels very kludgy
a
so which logs get recorded?
k
Copy code
#
VIEW
TYPE
TITLE
DATE 
TIME
USER
DETAILS
REMOVE
1	View	Audit	Summary	6/4/2024	8:57 am	-System-	Usage units consumed: 10 Concurrency units consumed: 1 Number of yields: 0 Input Summary: {"type":"mapreduce.InputSummary","dateCreated":"2024-06-04T14:56:31.648Z","seconds":0,"usage":10} Map Summary: {"type":"mapreduce.MapSummary","dateCreated":"2024-06-04T14:56:44.331Z","seconds":0,"usage":0,"concurrency":1,"yields":0} Reduce Summary: {"type":"mapreduce.ReduceSummary","dateCreated":"1970-01-01T00:00:00.000Z","seconds":0,"usage":0,"concurrency":1,"yields":0}	Remove
2	View	Error	Error in getInputData	6/4/2024	8:56 am	-System-	{"type":"error.SuiteScriptError","name":"UNEXPECTED_ERROR","message":null,"id":"bef8e13d-64da-4053-b060-9012550c1575-2d323032342e30362e3034","stack":["each(N/searchObject)","getInputData(/SuiteScripts/exportMessagesMR.js:42)"],"cause":{"type":"internal error","code":"UNEXPECTED_ERROR","details":null,"userEvent":null,"stackTrace":["each(N/searchObject)","getInputData(/SuiteScripts/exportMessagesMR.js:42)"],"notifyOff":false},"notifyOff":false,"userFacing":false}	Remove
3	View	Debug	Deployment Search	6/4/2024	8:56 am	-System-	{"type":"scriptdeployment","id":-1,"filters":[{"name":"scriptid","operator":"is","values":["customdeploy2"],"isor":false,"isnot":false,"leftparens":0,"rightparens":0},{"name":"scriptid","join":"script","operator":"anyof","values":["customscript_exportmessages_mr"],"isor":false,"isnot":false,"leftparens":0,"rightparens":0}],"columns":[{"name":"script","join":null,"summary":null,"label":"Script ID","type":null,"function":null,"formula":null,"sortdir":"NONE","whenorderedby":null,"whenorderedbyjoin":null,"whenorderedbyalias":null}],"settings":null,"title":null,"scriptId":null,"isPublic":false,"packageId":null}	Remove
4	View	Debug	Deployment Id: customdeploy2	6/4/2024	8:56 am	-System-	 	Remove
5	View	Debug	Last Run Time	6/4/2024	8:56 am	-System-
a
you can just tell me 😛
k
hard to read in pasted form
last runtime is null
Deployment Id: customdeploy2
this is not a unique value so I need to search
The search creates and logs {"type":"scriptdeployment","id":-1,"filters":[{"name":"scriptid","operator":"is","values":["customdeploy2"],"isor":false,"isnot":false,"leftparens":0,"rightparens":0},{"name":"scriptid","join":"script","operator":"anyof","values":["customscript_exportmessages_mr"],"isor":false,"isnot":false,"leftparens":0,"rightparens":0}],"columns":[{"name":"script","join":null,"summary":null,"label":"Script ID","type":null,"function":null,"formula":null,"sortdir":"NONE","whenorderedby":null,"whenorderedbyjoin":null,"whenorderedbyalias":null}],"settings":null,"title":null,"scriptId":null,"isPublic":false,"packageId":null}
then I try to run the search to get the one result
only way I know to run it is with an each
c
@Kris Wood Have you ever successfully run this search?
k
not in its current form, no
I accidentally overwrote the last known good version
I don't need it to be a search if there's a better way to update a script parameter
b
we will sadly be doing the same thing as last time
log the value of
scriptObj.id
a
okay, i found it... your filter operator for the script.scriptId is bad its a text field not an list/Record id number, so it needs to be IS not ANYOF
and as for the not doing .each when you're only ever gonna have a single result....
var result = deploymentSearch.run().getRange(0,1);
but it doesn't really matter i suppose
k
odd that in the code it's already is, not anyof, as you can see above
oh script.id anyof, nevermind
Script Id: customscript_exportmessages_mr
log output
a
right... that's a string
k
good call
switching to is
then I'll try your getRange
I like testing after each line change
a
good practice
k
anyof to is fixed it
"LAST RUN TIME 6/4/2024 95218 am"
success!
👍 1
a
for the record, I wouldn't do that in the getInput stage... cos it didn't actually RUN and do anything yet
you wanna set that script deployment runtime in the summarize when its succesfully done its thing
k
I need it to be before it runs the search
a
ok you know best, just seemed odd ¯\_(ツ)_/¯
k
otherwise it'll miss any messages created during execution when it runs next
b
depending on how active the account is
Copy code
deploymentRecord.setValue({
          fieldId: 'custscript_last_run_time',
          value: new Date()
        });
is not good enough
you dont want to set the last run time to now
you want to set it to when you last ran the search
if you were being very precise, your search would have both bounds on the created date filter, and then use the end of the bound for your last run time
and then later use that end bound for the start bound next time
c
Wouldn't a more robust solution be to make a record of the sync status per each message instance?
k
Good ideas but I'm crunched for time today so just going to go with what works. >.<
🙌 1
now to figure out why it doesn't find any messages 😞
b
the first time this runs, it should find no messages
since the last run time is basically the time the script ran
you need to manually set it further back
k
{"type":"message","id":-1,"filters":[{"name":"created","operator":"after","values":["Mon Jun 03 000000 PDT 2024"],"isor":false,"isnot":false,"leftparens":0,"rightparens":0}],"columns":[{"name":"internalid","join":null,"summary":null,"label":null,"type":null,"function":null,"formula":null,"sortdir":"NONE","whenorderedby":null,"whenorderedbyjoin":null,"whenorderedbyalias":null}],"settings":null,"title":null,"scriptId":null,"isPublic":false,"packageId":null}
I have it set to midnight the day before when null
but still no results even though I created a message this morning
b
that date value looks extra suspect, you probably want to manually put in the correct string
k
yeah it's a javascript Date
probably need N/format?
b
you probably want to be able to manually enter in the correct date time string before moving onto N/format
you are about to learn an annoyance relating to precision
k
Copy code
Last Run Time: 2024-06-04T16:39:14.000Z
ok it's now in NS format but still no result
b
what does your filter look like
k
Copy code
function getInputData() {
    try {
      // Get the last run time from the script parameter
      var lastRunTime = runtime.getCurrentScript().getParameter({ name: 'custscript_last_run_time' });
      log.debug({ title: 'Last Run Time', details: lastRunTime });

      // If last run time is null, set it to yesterday at midnight
      if (!lastRunTime) {
        lastRunTime = new Date();
        lastRunTime.setHours(0, 0, 0, 0);
        lastRunTime.setDate(lastRunTime.getDate() - 1);
      }

      // Load the deployment record
      var scriptObj = runtime.getCurrentScript();
      log.debug('Deployment Id: ' + scriptObj.deploymentId); // customdeploy_exportmessages_mr 
      log.debug('Script Id: ' + scriptObj.id); // customscript_exportmessages_mr

      // find the deployment record
      var deploymentSearch = search.create({
        type: "scriptdeployment",
        filters:
          [
            ["scriptid", "is", scriptObj.deploymentId],
            "AND",
            ["script.scriptid", "is", scriptObj.id]
          ],
        columns:
          [
            search.createColumn({ name: "script", label: "Script ID" })
          ]
      });
      log.debug({ title: 'Deployment Search', details: deploymentSearch });
      deploymentSearch.run().each(function (result) {
        log.debug({ title: 'Deployment Id: ', details: result.id });
        // load the deployment record
        var deploymentRecord = record.load({
          type: 'scriptdeployment',
          id: result.id
        });
        log.debug({ title: 'Testing after load', details: deploymentRecord.id });
        // set the last run time to now
        deploymentRecord.setValue({
          fieldId: 'custscript_last_run_time',
          value: new Date()
        });
        // save the deployment record
        deploymentRecord.save();
        return false;
      });

      // make sure lastRunTime is in NetSuite date format
      // lastRunTime should be a Date object initially convert it to string
      runTimeString = lastRunTime.toISOString();

      // use N/format to parse the string to a NetSuite date format

      lastRunTime = format.parse({ value: runTimeString, type: format.Type.DATETIME });
      log.debug({ title: 'Last Run Time', details: lastRunTime });
    } catch (e) {
      log.error({
        title: 'Error in getInputData',
        details: e.toString()
      });
    }

    // Search messages created after the last run time, the only column we need is internalid
    return search.create({
      type: 'message',
      filters: [
        ['created', 'onorafter', lastRunTime]
      ],
      columns: ['internalid']
    });
  }
Tested it out in saved search and it finds two results in this sandbox
b
thats not how format.parse works
and thats not a netsuite format
i heavily recommend figuring out what the correct string is before writing code to generate it
k
According to the NetSuite Saved Search Export chrome module:
Copy code
var messageSearchObj = search.create({
   type: "message",
   filters:
   [
      ["messagedate","onorafter","6/3/2024 12:00 am","6/3/2024 12:00 am"]
   ],
   columns:
   [
      search.createColumn({name: "internalid", label: "Internal ID"})
   ]
});
var searchResultCount = messageSearchObj.runPaged().count;
log.debug("messageSearchObj result count",searchResultCount);
messageSearchObj.run().each(function(result){
   // .run().each has a limit of 4,000 results
   return true;
});

/*
messageSearchObj.id="customsearch1717519555717";
messageSearchObj.title="Message Integration Search (copy)";
var newSearchId = messageSearchObj.save();
*/
b
that is good
you now know what it should look like
now compare it to what you are actually generating
k
already on it thanks
Ok I've got the script sending messages to the endpoint but it still isn't writing the updated last run time to the deployment.
Copy code
// Search for the deployment record using the internal ID of the script
        var deploymentSearch = search.create({
          type: 'scriptdeployment',
          filters: [
            ['script', 'anyof', scriptInternalId]
          ],
          columns: [
            search.createColumn({ name: 'internalid', label: 'Internal ID' })
          ]
        });

        deploymentSearch.run().each(function (result) {
          var deploymentId = result.id;

          // Load the deployment record
          var deploymentRecord = record.load({
            type: 'scriptdeployment',
            id: deploymentId
          });

          var newDate = new Date();
          // Set the last run time to now
          deploymentRecord.setValue({
            fieldId: 'custscript_last_run_time',
            value: newDate
          });

          log.debug({ title: 'checking if value was set', details: deploymentRecord.getValue({ fieldId: 'custscript_last_run_time' }) });

          // Save the deployment record
          var deploymentStatus = deploymentRecord.save();
          log.debug({ title: 'Deployment Record Saved', details: "Deployment ID: " + deploymentStatus + ", New Last Run Time: " + newDate });

          return false; // Break after the first deployment result
        });
Nevermind, found the error as soon as I pasted it
It's not actually finding the right deployment. There are two for this script. I only want the one with the right deployment scriptid
must have accidentally deleted that line somewhere along the way.
b
usually accomplished via a filter
k
Copy code
-            ['script', 'anyof', scriptInternalId]
+            ['script', 'anyof', scriptInternalId], "AND",
+            ['scriptid', 'is', scriptObj.deploymentId]