🔹 Introduction
User Event (UE) Scripts are server-side scripts that run on record actions: when they load, before saving, and after saving. They’re essential for enforcing business rules, validating data, and automating processes.
Each code block below includes a try–catch structure so you can see how to log and handle errors effectively.
🔹 Example 1: Add Default Memo on BeforeLoad
What this script does:
- Auto-fills the Memo field with default text when a new Sales Order is created.
/**
*@NApiVersion 2.1
*@NScriptType UserEventScript
*/
define([], () => {
const beforeLoad = (context) => {
try {
if (context.type === context.UserEventType.CREATE) {
const rec = context.newRecord;
rec.setValue({
fieldId: 'memo',
value: 'Generated by User Event Script'
});
log.debug('Success', 'Default memo set on new Sales Order');
}
} catch (e) {
log.error('Error in beforeLoad', e.message);
}
};
return { beforeLoad };
});
🔹 Example 2: Validate Required Field Before Submit
What this script does:
- Blocks saving a Customer if Email is missing.
/**
*@NApiVersion 2.1
*@NScriptType UserEventScript
*/
define([], () => {
const beforeSubmit = (context) => {
try {
if (context.type === context.UserEventType.CREATE || context.type === context.UserEventType.EDIT) {
const rec = context.newRecord;
const email = rec.getValue('email');
if (!email) {
throw Error('Email address is required before saving this customer.');
}
log.debug('Validation Passed', 'Email is present.');
}
} catch (e) {
log.error('Error in beforeSubmit', e.message);
throw e; // rethrow to stop record save
}
};
return { beforeSubmit };
});
🔹 Example 3: Send Email After Record Save
What this script does:
- When a new Customer is created, it emails the admin.
/**
*@NApiVersion 2.1
*@NScriptType UserEventScript
*/
define(['N/email', 'N/runtime'], (email, runtime) => {
const afterSubmit = (context) => {
try {
if (context.type === context.UserEventType.CREATE) {
const rec = context.newRecord;
const customerName = rec.getValue('companyname');
email.send({
author: runtime.getCurrentUser().id,
recipients: 'admin@company.com',
subject: 'New Customer Created',
body: `A new customer named ${customerName} has been added.`
});
log.debug('Success', `Email sent for new customer: ${customerName}`);
}
} catch (e) {
log.error('Error in afterSubmit (email)', e.message);
}
};
return { afterSubmit };
});
🔹 Example 4: Update Related Record After Submit
What this script does:
- When a Sales Order is created, it updates a custom checkbox on the related Customer record.
/**
*@NApiVersion 2.1
*@NScriptType UserEventScript
*/
define(['N/record'], (record) => {
const afterSubmit = (context) => {
try {
if (context.type === context.UserEventType.CREATE) {
const so = context.newRecord;
const customerId = so.getValue('entity');
if (customerId) {
const custRec = record.load({
type: record.Type.CUSTOMER,
id: customerId
});
custRec.setValue({
fieldId: 'custentity_has_salesorder',
value: true
});
custRec.save();
log.debug('Success', `Customer ${customerId} updated with has_salesorder flag.`);
}
}
} catch (e) {
log.error('Error in afterSubmit (update customer)', e.message);
}
};
return { afterSubmit };
});
🔹 Best Practices
- Always wrap logic in try–catch and use
log.error()
to capture failures. - Use beforeSubmit for validations that must block saving.
- Use afterSubmit for downstream actions (emails, integrations, updates).
- Keep heavy logic out of UE scripts → use Scheduled or Map/Reduce for large jobs.
✅ Key Takeaway
User Event Scripts let you:
- beforeLoad → Modify form before display
- beforeSubmit → Validate before database commit
- afterSubmit → Automate after save
By adding try–catch and logging, you’ll make scripts more robust and easier to debug.