Most Deluge scripts are written for the day everything works. The record has every field filled in, the other system answers in a second, and the reply is the one you expected. Error handling is the code for the other days: a blank quantity, an expired connection, an API that answers with an error message instead of data.
The syntax and behaviour described here were checked on Zoho’s Deluge help pages, release notes and community announcement on 11 November 2026. We build on Zoho, so read this with that in mind. If you are new to the language, start with our Deluge script examples and come back.
The short answer
- Put code that can fail inside
try. If it raises an exception, thecatchblock runs. If nothing fails, the catch block is skipped. - The catch variable tells you what happened. It carries the message, the line number, the type (
UserorSystem) and any data you attached. throwraises your own exception. Zoho added it on 25 August 2026. Use it when a reply or a value is wrong but Deluge itself would carry on.- An error reply is not an exception. A failed API call or a rejected CRM record often comes back as ordinary data. Check it, then throw.
- Never leave a catch block empty. Log the error and tell a person.
The try catch syntax
A try catch statement has two blocks. The name in brackets after catch is a variable of your choice; most developers call it e.
try
{
parts = {"bolt", "nut", "washer"};
info parts.get(10);
}
catch (e)
{
info e.lineNo;
info e.message;
}
info "The script carries on from here";
The list has three items, so asking for index 10 fails. Deluge stops the try block at that line, runs the catch block, then continues with the first statement after the whole try catch. Zoho’s help page shows the message for this case as “Given index 10 is greater than the list size”.
Deluge raises some exceptions on its own. Zoho names division by zero and reading an invalid list index as examples. These are system exceptions. The ones you raise yourself with throw are user exceptions.
What the catch variable holds
The variable is read-only. You can read its attributes but not change them.
| Attribute | What it holds | Example |
|---|---|---|
e.message | The error text | Given index 10 is greater than the list size |
e.lineNo | The line where the exception was raised | The number of the failing line in your script |
e.type | Who raised it | System for runtime errors, User for a throw |
e.data | Extra information passed with throw | An API reply, a record ID, or null if nothing was passed |
One detail to know: the attribute table on Zoho’s try catch page names the line attribute line, while the examples on the same page and the throw page use e.lineNo. We use e.lineNo, as the examples do. If you only need a quick look while testing, info e; prints the line and the message together.
The throw statement, new in August 2026
Before throw, a catch block could only see errors that Deluge raised. A script that received a bad reply had to carry its own flags and if checks to the end. Zoho’s release notes list the throw statement on 25 August 2026, and it closes that gap.
try
{
if (quantity <= 0)
{
throw "Order quantity must be more than zero";
}
total = quantity * unit_price;
}
catch (e)
{
info e.message; // Order quantity must be more than zero
info e.type; // User
}
Statements after a throw on the same path do not run. Control moves to the nearest catch block that can take it.
throw accepts three things:
- Text. The text becomes the message.
- A map. It must have a
messagekey and may have adatakey holding any Deluge value. Use this to pass the evidence along with the error. - An exception variable. This re-throws an error you have already caught, keeping its original message, line number, type and data.
throw {"message": "Stock check failed", "data": {"item_id": item_id, "on_hand": on_hand}};
If no catch block handles the exception, Zoho states that the script terminates and the execution is marked as failed. That is useful in itself: a failure you raise on purpose shows up as a failure, not as a script that “succeeded” while doing nothing.
What raises an exception, and what does not
This is where most error handling goes wrong. A try block only helps when something actually raises an exception, and many failures do not.
| Situation | Raises an exception? | What to do |
|---|---|---|
| Division by zero, invalid list index | Yes, a system exception | Catch it, or check the value first |
invokeurl waits more than 40 seconds | Yes. Zoho documents a socket timeout error and the task is ended | Catch it and decide whether to retry later |
| An API answers with an error status | Not by itself. With detailed: true you receive the status code as data | Check responseCode and throw |
| A Zoho CRM task is rejected, for example a required field is missing | No. zoho.crm.createRecord returns a map with "status":"error" | Check the reply and throw |
| A business rule is broken | Only if you throw | Throw with a clear message |
| The script reaches an execution limit or a function timeout | Zoho’s pages do not say a catch block will see these | Do not rely on catching them. Design to stay under the limit |
Zoho’s own announcement of throw makes the same point about API calls: an invokeUrl task is marked successful when the call is made, not when the other system does what you asked.
Pattern 1: an API call that fails properly
Ask for the detailed response, check the status code, and turn a bad status into an exception. The timeout and the error reply then arrive in the same catch block.
try
{
response = invokeurl
[
url: "https://api.example.com/v1/orders"
type: POST
parameters: payload.toString()
connection: "orders_api"
detailed: true
];
status = response.get("responseCode");
if (status != 200 && status != 201)
{
throw {"message": "Order API returned " + status, "data": response.get("responseText")};
}
order = response.get("responseText");
}
catch (e)
{
sendmail
[
from: zoho.adminuserid
to: "ops@yourcompany.com"
subject: "Order sync failed"
message: "Line " + e.lineNo + ": " + e.message + "<br>" + e.data
]
}
With detailed: true the reply is a map with three keys: responseCode, responseText and responseHeader. Without it you receive only the content, and an error page looks like a normal answer. Our guide to Deluge invokeurl API calls covers the parameters, connections and limits in full.
Pattern 2: a Zoho task that returns an error
Integration tasks such as zoho.crm.createRecord reply with a map either way. On success the map includes the new record’s id. On failure Zoho’s help page shows a map with code, details, message and status, for example MANDATORY_NOT_FOUND when a required field is missing. Nothing is raised, so the next line of your script runs as if the record existed.
try
{
reply = zoho.crm.createRecord("Contacts", contact);
if (reply.get("id") == null)
{
throw {"message": "Contact was not created: " + reply.get("message"), "data": reply};
}
contact_id = reply.get("id");
}
catch (e)
{
info e.message;
info e.data;
}
The same habit applies to Zoho Books, Zoho Inventory and the other integration tasks: read the reply before you use it. In Zoho CRM, each of these tasks also uses API credits; see our Zoho CRM API limits guide.
Pattern 3: validate in one function, handle in the caller
An exception that is not caught inside a function passes up to the script that called it, and keeps going up until a catch block is found. That lets you write a check once and reuse it.
// A custom function
void checkOrder(int quantity)
{
if (quantity <= 0)
{
throw "Order quantity must be more than zero";
}
}
// The script that calls it
try
{
thisapp.checkOrder(input.Quantity);
// create the order
}
catch (e)
{
info "Order rejected: " + e.message;
}
The function call above uses Zoho Creator’s thisapp form. In other Zoho services, call the function the way that service defines.
When an inner block needs to note the error but cannot fix it, log it and pass it on with throw e;. The outer catch receives the original message, line number, type and data.
try
{
try
{
// reserve stock
}
catch (inner)
{
info "Stock step failed: " + inner.message;
throw inner;
}
}
catch (outer)
{
// one place that alerts a person
}
What to do inside catch
A catch block has two jobs: leave a record, and tell someone who can act.
- While testing, use
info. In Zoho Creator the output is visible to Super Admins, Admins and Developers, and Zoho caps the combinedinfoandalertoutput of a function at 500 KB, so do not print whole API replies inside a loop. - In production, write an error record. A small log form in Creator, or a custom module in Zoho CRM, with the script name, the record ID,
e.message,e.lineNoand the time. A log you can filter is worth more than a mailbox full of alerts. - Send one alert per run, not one per record. Zoho’s Deluge limitations page lists 500 emails per user per day. A loop that emails on every failed record can use that up in one bad night. Collect the failures in a list and send a single summary after the loop.
- Use the built-in failure views. Zoho CRM lists failed function executions under Setup > Developer Hub > Functions > Failures, with the reason, and lets you rerun them one at a time or in bulk. A function that catches every error and hides it will never appear there, which is one more reason to re-throw what you cannot handle.
Try catch in Zoho Creator forms
Zoho’s try catch page lists where the statement can be used in Zoho Creator: the form workflow events (On Load, On Validate, On Success, On User Input, and adding or deleting a subform row), schedules, approval and payment workflows, custom functions and report actions. For a record being deleted, only On Validate and On Success are listed.
Keep two things apart in a form:
- Telling the user their entry is wrong. That is validation. In On Validate, use
alertfollowed bycancel submit. Zoho documents thatcancel submitworks only in the On Validate section of the created and edited events, and that the other tasks in that section are rolled back, except send mail tasks and API calls. - Handling a step that failed behind the scenes. That is try catch. An On Success script that pushes the record to another system should catch the failure, log it and alert the administrator. The user has already saved the record and cannot fix a broken connection.
Does it work in Zoho CRM and other Zoho apps?
Zoho’s list of services that support Deluge runs to about 40, from Zoho CRM, Books and Desk to Flow, Inventory and Creator. The try catch help page describes Zoho Creator events and does not give a service-by-service list. The throw help page includes an example that reserves stock across Zoho CRM and Zoho Inventory, and try catch is mentioned in the Deluge release notes as far back as 11 January 2022.
The practical rule: write the failure path, then force it in the service you are using. Point the call at a wrong address, or pass a blank required field, and confirm that the catch block runs and the alert arrives. Do this in a sandbox or a test copy where you have one. For how functions are triggered and timed in Zoho CRM, see our Zoho CRM custom functions guide.
Common mistakes
- An empty catch block. The error is swallowed and the script reports success.
- Wrapping the whole script in one try. You learn that something failed but not which step. Wrap each risky call, or throw messages that name the step.
- Catching, logging and carrying on with missing data. If the customer was not created, the invoice step must not run. Throw again, or return.
- Retrying inside a loop without a limit. Every retry counts against statement and call limits. Zoho’s limitations page lists 5,000 statements per function and 2,000 webhook calls per user per day as general figures, and individual services set their own.
- Using exceptions for ordinary branches. An empty search result is not an error. Keep
iffor expected cases andthrowfor the ones that should stop the work.
When the job needs long retries, queues or guaranteed delivery, Deluge may be the wrong place for it. Our Zoho Flow vs Deluge comparison explains when to move that logic to middleware.
Checklist before a script goes live
- Every call to another system sits inside a try block.
- Every
invokeurlusesdetailed: trueand checksresponseCode. - Every integration task reply is checked before its values are used.
- Bad replies and broken rules are turned into exceptions with
throw. - No catch block is empty.
- Each failure writes a log record with the message, line number and record ID.
- One person receives one alert per failed run.
- Errors the script cannot fix are re-thrown, so the run is marked as failed.
- The failure path has been forced and seen to work in the service where the script runs.
If you have scripts that fail quietly, or want an existing set reviewed, our Deluge development service covers reviews and fixes as well as new functions, and support and maintenance covers the monitoring afterwards.
Frequently asked questions
Frequently asked questions
Does Deluge have try catch?
Yes. Deluge has a try catch statement: code that might fail goes in the try block, and the catch block runs only if an exception is raised. The throw statement, added in August 2026, lets a script raise its own exceptions as well.
What is the syntax of try catch in Deluge?
Write try followed by a block in curly braces, then catch with a variable name in brackets and a second block: try { ... } catch (e) { ... }. Inside the catch block, e.message holds the error text and e.lineNo the line number. After the catch block finishes, the script continues with the next statement.
How do I get the error message and line number in Deluge?
Read them from the catch variable. e.message returns the error text and e.lineNo returns the line where the exception was raised. e.type returns User or System, and e.data returns anything passed with a throw. The statement info e; prints the line and message together.
What does the throw statement do in Deluge?
throw stops the current path of the script and raises an exception that the nearest catch block receives. It accepts text, a map with a message key and an optional data key, or a caught exception variable to re-throw. If nothing catches it, the script ends and the execution is marked as failed.
Does try catch catch a failed invokeurl call?
Only partly. Zoho documents that invokeurl throws a socket timeout error after 40 seconds, which a catch block can handle. An error status from the other system is returned as data, so add detailed: true, check responseCode, and throw your own exception when the status is not a success.
Can I use try catch in Zoho CRM functions?
Deluge is the same language across Zoho services, and Zoho's throw help page includes an example working with Zoho CRM and Zoho Inventory. The try catch help page itself lists Zoho Creator events only, so test the failure path in the service you use before relying on it.
