Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The NetSuite Pro

The NetSuite Pro Logo The NetSuite Pro Logo

The NetSuite Pro Navigation

  • Home
  • About Us
  • Tutorials
    • NetSuite Scripting
    • Advanced PDF Templates in NetSuite
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask A Question
  • Home
  • About Us
  • Tutorials
    • NetSuite Scripting
    • Advanced PDF Templates in NetSuite
  • Blog
  • Contact Us
Home/ NetSuite Scripting/Error Handling & Governance in SuiteScript 2.1

Error Handling & Governance in SuiteScript 2.1

🔹 Introduction

Two critical skills for NetSuite developers are:

  1. Error Handling → How to catch, log, and handle errors in scripts without breaking user workflows or losing data.
  2. Governance → NetSuite enforces usage units (governance limits) on API calls. Scripts must manage these limits to avoid abrupt termination.

🔹 Part 1: Error Handling

Why It Matters

  • Errors stop your script unless handled.
  • Logging errors helps debugging.
  • Users/admins need clear messages (not just “An unexpected error occurred”).

Example 1: Simple Try–Catch

/**
 *@NApiVersion 2.1
 *@NScriptType UserEventScript
 */
define([], () => {
    const beforeSubmit = (context) => {
        try {
            // Example: required field check
            const rec = context.newRecord;
            const email = rec.getValue('email');
            
            if (!email) {
                throw new Error('Email is required before saving this record.');
            }

            log.debug('Validation Passed', 'Email present.');
        } catch (e) {
            // Log the error for debugging
            log.error('Validation Error', e.message);

            // Rethrow to stop the save
            throw e;
        }
    };
    return { beforeSubmit };
});

💡 Explanation:

  • try runs risky code.
  • catch (e) logs error details.
  • throw e stops record save with a readable error.

Example 2: Catch & Continue

/**
 *@NApiVersion 2.1
 *@NScriptType ScheduledScript
 */
define(['N/search'], (search) => {
    const execute = () => {
        try {
            const results = search.create({
                type: search.Type.CUSTOMER,
                filters: [['isinactive', 'is', 'F']],
                columns: ['entityid']
            }).run().getRange({ start: 0, end: 10 });

            results.forEach(result => {
                try {
                    const name = result.getValue('entityid');
                    if (!name) throw new Error('Missing customer name');
                    
                    log.debug('Customer', name);
                } catch (innerErr) {
                    // Handle per-record errors without failing whole script
                    log.error('Customer Error', innerErr.message);
                }
            });
        } catch (e) {
            log.error('Script Error', e.message);
        }
    };
    return { execute };
});

💡 Explanation:

  • Wrap per-record operations in an inner try–catch.
  • Keeps script running even if one record fails.

Example 3: Logging Stack Traces

log.error({
    title: 'Error in map stage',
    details: JSON.stringify(e)  // Logs stack trace, name, and message
});

💡 Always log more than just e.message → use JSON.stringify(e) for debugging.


🔹 Part 2: Governance

What is Governance?

NetSuite limits how much work a script can do by assigning usage units to API calls.

Examples (approximate):

  • record.load() → 10 units
  • record.save() → 20 units
  • search.run() → 10 units
  • record.submitFields() → 4 units

If a script runs out of units → SSS_USAGE_LIMIT_EXCEEDED error.


Checking Remaining Usage

/**
 *@NApiVersion 2.1
 *@NScriptType ScheduledScript
 */
define(['N/runtime'], (runtime) => {
    const execute = () => {
        try {
            const script = runtime.getCurrentScript();
            log.debug('Remaining Usage', script.getRemainingUsage());
        } catch (e) {
            log.error('Error checking usage', e.message);
        }
    };
    return { execute };
});

Example 1: Stop Early if Low Usage

if (runtime.getCurrentScript().getRemainingUsage() < 100) {
    log.debug('Governance', 'Stopping early to avoid usage exceeded.');
    return; // exit script cleanly
}

Example 2: Rescheduling (Scheduled Script)

/**
 *@NApiVersion 2.1
 *@NScriptType ScheduledScript
 */
define(['N/runtime', 'N/task'], (runtime, task) => {
    const execute = () => {
        try {
            const script = runtime.getCurrentScript();

            if (script.getRemainingUsage() < 200) {
                log.debug('Governance', 'Low usage, rescheduling script.');

                task.create({
                    taskType: task.TaskType.SCHEDULED_SCRIPT,
                    scriptId: script.id,
                    deploymentId: script.deploymentId
                }).submit();

                return;
            }

            // Continue processing logic here
        } catch (e) {
            log.error('Error in governance check', e.message);
        }
    };
    return { execute };
});

💡 Explanation:

  • Rescheduling lets the script resume later with a fresh usage quota.
  • Important for long-running Scheduled Scripts.

Example 3: Use Map/Reduce for Heavy Loads

Instead of manually rescheduling, use a Map/Reduce script → NetSuite automatically yields and resumes as needed.


🔹 Best Practices for Error Handling & Governance

  • Always wrap risky code in try–catch.
  • Use per-record try–catch to keep batch jobs running.
  • Log errors with context (record ID, field, etc.).
  • Use runtime.getCurrentScript().getRemainingUsage() frequently.
  • Prefer submitFields() over full load + save for small updates.
  • Break work into chunks → process in batches of 100 or less.
  • For big data jobs, use Map/Reduce (built-in resumption).

✅ Key Takeaway

  • Error Handling → Prevents script crashes, improves debugging.
  • Governance Management → Ensures scripts finish cleanly without exceeding limits.
  • Together, they make your SuiteScripts robust, scalable, and production-ready.
Share
  • Facebook

Sidebar

Ask A Question

Stats

  • Questions 6
  • Answers 6
  • Best Answers 0
  • Users 2
  • Popular
  • Answers
  • Rocky

    Issue in running a client script in NetSuite SuiteScript 2.0 ...

    • 1 Answer
  • admin

    How can I send an email with an attachment in ...

    • 1 Answer
  • admin

    How do I avoid SSS_USAGE_LIMIT_EXCEEDED in a Map/Reduce script?

    • 1 Answer
  • admin
    admin added an answer The issue is usually caused by following Wrong script file… September 14, 2025 at 10:33 pm
  • admin
    admin added an answer Steps to send an Invoice PDF by email: define(['N/email', 'N/render',… August 28, 2025 at 3:05 am
  • admin
    admin added an answer This error means your script hit NetSuite’s governance usage limit… August 28, 2025 at 3:02 am

Top Members

Rocky

Rocky

  • 1 Question
  • 21 Points
Begginer
admin

admin

  • 5 Questions
  • 2 Points

Trending Tags

clientscript netsuite scripting suitescript

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help

Footer

© 2025 The NetSuite Pro. All Rights Reserved