1

According to Netsuite's documentation, User Event Scripts are an appropriate choice for adding custom validation for records. My question is: what is the proper way to handle a record that fails validation in a user event script?

As a more concrete example, I have a user event script that validates vendor bill records in the beforeSubmit entry point according to criteria unique to our business. The way I'm currently dealing with vendor bills that fail is to throw an error using error.create in the N\error module. Here's an example of how this looks:

/**
 * @NApiVersion 2.1
 * @NScriptType UserEventScript
 */
define(['N/record', 'N/error'],
    (record, error) => {
        const isValid = (newRecord) => {
            // Make sure the record is valid...
            return false;
        };

        const invalidRecordError = () => {
            const err = error.create({
                name: 'INVALID_INVOICE',
                message: 'This invoice is not up to snuff.',
                notifyOff: true
            });

            return err;
        };

        const beforeSubmit = (context) => {
            if (!isValid(context.newRecord)) {
                // Invalidate record and prevent submit.
                throw invalidRecordError();
            }        
        };

        return {beforeSubmit}
    }
);

This approach does what I want -- records that don't pass validation aren't saved. My only issue is that the error messages aren't displayed in a very useful way to the user. For example, if a record is submitted via CSV import, the error message shown in the results.csv is a JSON version of the error object and includes a stack trace.

So how can I prevent the record from being saved while providing a user-friendly error? Ideally, the error shown to the end-user would just be the message property of the error object. Is there an alternative to throwing an error that I'm not aware of?

Adam Richard
  • 460
  • 4
  • 13

1 Answers1

2

You may be able to abstract your rules into a library that could be called by both Client and UserEvent scripts.

A client saveRecord() function can display a message and return false if a record cannot be saved. This covers the case where there is a user in front of the screen and may be able to recover the invalid situation without re-doing their data entry.

A beforeSubmit() UserEvent script handles all the server side interactions where there is no UI in which to display a nicely formatted message and no recovery is possible.

e.g.

//lib.js
**
* @NAPIVersion 2.1
*/

define(['N/search'], function(search){ // or whatever NS APIs you need
   
   function validate(record){
       throw new Error('reason for error');
       return true;
   }

   return{
      validate: validate
   };
})
//UE.js
/**
 * @NApiVersion 2.1
 * @NScriptType UserEventScript
 */
define(['./lib'], function(sharedLib){

function beforeSubmit(ctx){
    // check type etc
    sharedLib.validate(ctx.newRecord)
}

return {
    beforeSubmit:beforeSubmit
}
});
//Client.js
/**
 * @NApiVersion 2.1
 * @NScriptType ClientScript
 */
define(['./lib'], function(sharedLib){
function saveRecord(ctx){
    // check type etc
    try{
       sharedLib.validate(ctx.currentRecord);
       return true;
    }catch(e){
       alert(e.message);
       return false;
    }
}

return {
    saveRecord:saveRecord
}
});
bknights
  • 14,408
  • 2
  • 18
  • 31
  • I presume the library must be defined as a module, which later is supposed to be loaded by both UserEvent scripts and Client scripts. But could you please suggest what is the proper way do define such a module, where to put it? – d.k May 03 '23 at 18:28
  • 1
    The lib would be at some file cabinet path. I generally put them at the same level `./` but any relative path works. The syntax is just the same as any suitescript file but without a script type annotation. – bknights May 03 '23 at 22:18
  • This is a useful approach for centralizing the validation logic for sure. I do still wonder about the how to control the error response from CSV uploads (Netsuite returns a *response.csv* file that lists errors for any invalid records), but for all other user facing parts, this approach will work well. – Adam Richard May 04 '23 at 03:18
  • For CSV uploads the user who started the CSV import does receive an email summary of the process and can review errors after receiving the completion notice. You can also log the errors with a stable title prefix and create a saved search on Server Script Errors that match the prefix and email that to selected users on a schedule. – bknights May 04 '23 at 16:52