VERSICH

SuiteScript Error Page: Use N/error Without Exposing Details

suitescript error page: use n/error without exposing details

When a SuiteScript operation fails, NetSuite needs enough information to explain the problem without exposing implementation details to the wrong user. The SuiteScript Error Page is part of that failure experience, while the `N/error` module gives developers a structured way to create and throw meaningful errors.

To use the SuiteScript Error Page with `N/error`, create a named error with `error.create()`, include a user-appropriate message, decide whether NetSuite should notify administrators, and throw the error from the failing code path. Catch the error only when the script can recover or return a controlled response. Otherwise, allowing the structured error to propagate gives NetSuite the information it needs to display the failure page and record the execution details.

This distinction matters. A custom error is not the same as a complete error-handling strategy. Developers also need to separate safe user messages from internal diagnostics, avoid leaking record IDs or credentials, account for script type differences, and test how the failure appears in the relevant execution context.

What does the SuiteScript Error Page actually do?

The SuiteScript Error Page presents an error when server-side SuiteScript fails without producing a successful response. Its exact appearance and available diagnostic detail depend on the script type, execution context, user permissions, and whether the failure was handled before reaching NetSuite’s default response behavior.

The `N/error` module does not independently create a web page. Instead, it creates a SuiteScript error object that NetSuite can process when the script throws it. In a Suitelet, for example, an unhandled error can stop request processing and return an error response rather than the intended form or page. In a User Event or scheduled script, the same error affects execution logs, deployment status, notifications, and downstream processing rather than presenting a browser page to an end user.

That distinction is one of the most important implementation details:

  • `N/error` creates a structured error.

  • `throw` stops the current execution path and passes the error to NetSuite.

  • The script type determines how the failure is surfaced.

  • The error page is only one possible presentation of the failure.

A generic JavaScript exception such as `throw new Error('Failed')` can stop execution, but it does not communicate the same business meaning as a named NetSuite error created through `N/error`. A custom error name gives administrators and developers a stable identifier for searching logs, reviewing alerts, and distinguishing validation failures from system failures.

For broader SuiteScript development guidance, our NetSuite development services cover custom scripts, automation, integrations, and technical troubleshooting.

How do you create an error with the N/error module?

Create an error with `error.create()` and pass an options object containing a name and message. The resulting error object should then be thrown when the script cannot safely continue.

A basic SuiteScript 2.1 example looks like this:

/**
 * @NApiVersion 2.1
 */
define(['N/error'], (error) => {
    function validateCustomer(customerId) {
        if (!customerId) {
            const validationError = error.create({
                name: 'MISSING_CUSTOMER_ID',
                message: 'A customer is required before this action can continue.',
                notifyOff: true
            });

            throw validationError;
        }

        return true;
    }

    return {
        validateCustomer
    };
});

The `name` should be stable, specific, and suitable for logs. Use a naming convention that identifies the business or technical condition, such as `MISSING_CUSTOMER_ID`, `INVALID_DATE_RANGE`, or `INTEGRATION_AUTH_FAILURE`. Avoid putting changing values into the error name. A record number or external transaction ID belongs in controlled diagnostic logging, not in the identifier that classifies the error.

The `message` should explain what happened and what the user should do next. A message such as “Validation failed” is technically valid but operationally weak. A message such as “Select a customer before submitting this form” is clearer for a user interacting with a Suitelet.

`notifyOff` controls whether NetSuite should suppress email notification for that error. Setting it to `true` is appropriate for expected validation conditions that users can correct. It is not a substitute for monitoring unexpected failures. If a scheduled process repeatedly fails because of a configuration problem, suppressing every notification can hide an operational issue.

What should a SuiteScript error message contain?

A SuiteScript error message should contain the safe explanation, the corrective action, and enough context for the user to understand what to do next. It should not contain secrets, full stack traces, authentication tokens, internal credentials, or unnecessary implementation details.

We recommend separating error information into three layers:

  1. User message: A concise explanation displayed through the Suitelet response or error page.

  2. Developer diagnostic: Technical context written to the execution log or a controlled monitoring system.

  3. Stable error name: A searchable identifier shared by the user-facing and diagnostic paths.

For example, this is a poor message:

message: 'REST call failed with token abc123 for customer 45821'

It exposes both an authentication value and an internal record identifier. A safer approach is:

const integrationError = error.create({
    name: 'CUSTOMER_SYNC_FAILED',
    message: 'The customer could not be synchronized. Try again later or contact your administrator.',
    notifyOff: false
});

log.error({
    title: integrationError.name,
    details: {
        customerId,
        endpointName: 'CustomerSync',
        reason: 'Remote system rejected the request'
    }
});

throw integrationError;

The example still requires careful logging. A custom object written to the execution log should not include authorization headers, passwords, or full request payloads if those payloads contain personal or financial data. NetSuite execution logs are useful for troubleshooting, but they are not automatically a safe place for unrestricted sensitive information.

How do you throw an N/error object correctly?

Throw the object returned by `error.create()` at the point where the script knows it cannot continue safely. Do not create an error and then ignore it, and do not catch it immediately unless the catch block has a meaningful recovery or presentation purpose.

This pattern is correct:

const errorObject = error.create({
    name: 'INVALID_ITEM_CONFIGURATION',
    message: 'The selected item is not configured for this transaction.',
    notifyOff: true
});

throw errorObject;

This pattern is ineffective:

const errorObject = error.create({
    name: 'INVALID_ITEM_CONFIGURATION',
    message: 'The selected item is not configured for this transaction.',
    notifyOff: true
});

// The script continues as if no problem occurred.
return false;

Returning `false` can be appropriate when the caller explicitly knows how to handle that result. It is not equivalent to throwing an error. If the operation must not proceed, execution should stop at the validation boundary.

A common mistake is to catch an error and throw a vague replacement:

try {
    processTransaction();
} catch (e) {
    throw new Error('Something went wrong');
}

This discards the original error name and useful diagnostic context. If the script needs to add context, preserve the original details in the log and throw a deliberate replacement only when the new message is safer or more meaningful:

try {
    processTransaction();
} catch (e) {
    log.error({
        title: 'Transaction processing failed',
        details: e
    });

    throw error.create({
        name: 'TRANSACTION_PROCESSING_FAILED',
        message: 'The transaction could not be completed. Contact your administrator with the time of the attempt.',
        notifyOff: false
    });
}

How does error handling differ by script type?

Error handling differs because each SuiteScript type has a different execution contract. A Suitelet must decide what to return to a browser request, while a User Event must protect the transaction lifecycle and a scheduled script must expose failures to monitoring and restart procedures.

Suitelets

A Suitelet typically serves a form, page, or server-side request. If validation fails before the response is written, the script can throw a structured error. If the Suitelet has already begun constructing a response, developers need to design the flow carefully so that the user receives either a useful error page or a controlled response rather than a partially rendered result.

For expected validation, a Suitelet often provides a better experience by returning the form with an inline message or a clear redirect. For an unexpected server failure, allowing a structured error to reach NetSuite preserves the fact that the request failed.

Do not expose raw exception objects directly in an HTML response. A raw object can include implementation details that are useful to a developer but confusing or unsafe for an end user.

User Event scripts

A User Event runs around record operations such as create, edit, or submit. Throwing an error in `beforeSubmit` can prevent the record from saving, which is appropriate when a required business rule is violated. Throwing from `afterSubmit` does not undo every external action that already occurred, so the integration or follow-up process must account for partial completion.

For example, if an `afterSubmit` script creates a related record and then fails while sending an external notification, the original transaction might already exist. The error design should distinguish between “the transaction must not save” and “the transaction saved, but follow-up processing requires attention.”

Our guide on finding the real cause of a NetSuite User Event script permissions error covers the separate investigation of role permissions, execution context, and deployment authorization. The `N/error` module improves failure reporting, but it does not grant permissions or correct an authorization design.

Scheduled and Map/Reduce scripts

Scheduled and Map/Reduce scripts need errors that support retry and operational review. A message that says “failed” is not enough when a deployment may process hundreds or thousands of records. Include a stable error name, identify the processing stage, and log the relevant internal identifier without exposing sensitive data.

Map/Reduce scripts also require careful decisions about whether a single bad record should fail the entire stage or be isolated and reported for later correction. Throwing from every record-processing failure can reduce throughput and make recovery harder. In contrast, silently skipping failures creates data reconciliation problems.

When should you catch an N/error exception?

Catch an `N/error` exception when the script can recover, translate the message into a safe response, or complete required cleanup. Do not catch an exception merely to prevent the error page from appearing.

A useful catch block has a defined purpose:

  • It retries a transient operation within a controlled limit.

  • It records structured diagnostic context.

  • It returns a safe message to a Suitelet user.

  • It marks a record for reconciliation.

  • It performs cleanup before rethrowing the error.

A catch block that only logs and suppresses the exception is dangerous:

try {
    submitRecord();
} catch (e) {
    log.error({
        title: 'Submit failed',
        details: e
    });
}

The script may appear successful to the caller even though the record was not submitted. If the failure cannot be recovered, rethrow it:

try {
    submitRecord();
} catch (e) {
    log.error({
        title: 'Submit failed',
        details: e
    });

    throw e;
}

If you need to show a controlled message in a Suitelet, catch the failure, log the original exception, and use a safe response path. The response should tell the user what action is possible, such as correcting a field, trying again, or contacting an administrator. It should not reveal stack traces or internal module paths.

How do you test the SuiteScript Error Page?

Test the error page and the underlying error object in the same deployment context where users will encounter the failure. A script that behaves correctly in the SuiteScript Debugger can produce a different practical result when run by a restricted role, from a scheduled deployment, or through a browser request.

A reliable test checks all of the following:

  1. The expected validation condition creates the intended `name` and `message`.

  2. The script stops at the correct point after `throw`.

  3. The user sees a safe message rather than raw implementation details.

  4. The execution log contains useful diagnostics.

  5. `notifyOff` produces the intended notification behavior.

  6. The error does not expose credentials, tokens, or unnecessary personal data.

  7. The failure does not leave a transaction or integration in an unknown partial state.

  8. A corrected input follows the successful path without retaining stale error state.

Use separate tests for expected validation and unexpected system failure. An expected validation error should be easy for a user to correct. An unexpected failure should generate enough operational evidence for an administrator to investigate, including the deployment, execution context, script version, timestamp, and affected record where appropriate.

Testing should also cover permissions. A script may work under an administrator role but fail for the role that actually launches the process. Review the deployment role, record permissions, subsidiary restrictions, and access to related records before deciding that an error page implementation is complete.

Common mistakes with N/error and error pages

The most serious mistakes are not syntax errors. They are design errors that make failures difficult to diagnose or unsafe to expose.

Using generic messages everywhere makes logs and support requests difficult to classify. Stable names such as `INVALID_DATE_RANGE` and `CUSTOMER_SYNC_FAILED` provide much better operational signals.

Including sensitive values in messages creates unnecessary exposure. Keep credentials, authorization headers, full payloads, and confidential business data out of user-facing errors and execution logs.

Suppressing every notification prevents expected validation failures from creating noise, but it also hides recurring production failures. Set notification behavior according to the operational importance of the condition.

Catching without recovery creates false success. If the script cannot complete its intended operation, rethrow the error or return an explicit failure response.

Assuming the error page is universal leads to poor testing. Suitelets, User Events, scheduled scripts, and Map/Reduce deployments surface errors through different channels.

Failing to preserve context causes support teams to ask for the same information repeatedly. Log the script deployment, execution stage, record type, internal ID when appropriate, and the original exception details, while applying data-minimization rules.

For complex error flows, integration failures, or deployments that combine SuiteScript with external systems, contact Versich to discuss a controlled debugging and recovery approach.

Conclusion

The SuiteScript Error Page works best when it is supported by deliberate error design rather than treated as a replacement for error handling. Use `N/error` to create stable, meaningful errors, throw them when execution cannot safely continue, and catch them only when the script has a real recovery or presentation purpose.

Keep user messages safe and actionable. Put technical context in controlled logs, preserve the original failure when translating errors, and test the result under the actual deployment role and script type. With that approach, SuiteScript failures become easier to understand, safer to expose, and more reliable to resolve.

Frequently Asked Questions

What is the SuiteScript Error Page?

The SuiteScript Error Page is the failure experience NetSuite can display when server-side SuiteScript stops with an unhandled error. It is not created directly by `N/error`; the module creates a structured error that NetSuite can process. The script type and execution context determine whether the result appears in a browser, an execution log, a deployment notification, or another operational channel.

How do I use N/error in SuiteScript?

Import `N/error`, call `error.create()` with a stable `name`, a safe `message`, and the desired `notifyOff` value, then throw the returned object. For example, `throw error.create({ name: 'VALIDATION_FAILED', message: 'Correct the highlighted values.', notifyOff: true });` stops the current execution path and gives NetSuite a structured failure.

Is the N/error module required for every SuiteScript error?

No. JavaScript exceptions and other NetSuite errors can still stop execution, but `N/error` is the better choice when you need a named, intentional, and searchable business or validation error. It does not replace logging, monitoring, permission review, or recovery design.

Should I catch an N/error exception or let it reach NetSuite?

Let it reach NetSuite when the script cannot recover and the failure should be visible as an execution failure. Catch it when you can retry safely, return a controlled Suitelet response, perform cleanup, or record a reconciliation task, and rethrow it when the operation remains unsuccessful.

How much does it cost to add N/error handling?

The `N/error` module itself does not require a separate software purchase. The practical cost comes from designing, testing, documenting, and monitoring the failure paths, especially when scripts process financial records or integrate with external systems. The effort depends on the number of script types, deployments, roles, and recovery scenarios involved.

Is a custom error page better than the NetSuite SuiteScript Error Page?

A custom response is better for expected user-correctable validation because it can keep the user in a controlled form flow. The NetSuite error page is appropriate for unhandled failures that require execution visibility, but it should not be treated as the only user experience for every error. The right choice depends on whether the condition is recoverable, who sees it, and whether processing has already changed data.