Most mistakes in a script stop it until its next start. Knowing which ones do, where they show up and how their texts are built saves a lot of guessing.
Where errors show up
| Where | What it tells you |
|---|---|
| The behavior stopped with an error, at the top of the bot's page | The script started, then stopped because of an error. The alert shows the whole text, with Copy and Dismiss. The bot's Behavior badge, and its column in Bot Manager, say Failed. |
| Couldn't start the behavior after Play, or Couldn't run the package after Run | The start failed. When the code couldn't even be loaded, this toast is the only sign, and it gives no reason. |
| Couldn't load the selection, after confirming Load a behavior selection | The package couldn't be loaded on the bot, for example because a dependency isn't installed or the package isn't compatible with your Asterobot. |
| The editor's error badge | A problem found before running, such as a syntax error, an import of a file that doesn't exist, or a misspelled function. |
When the code couldn't be loaded, the bot's Settings tab gives the reason under Package settings, as The entry function explains.
The alert goes away when the script starts again, when you load or unload a package, or when the bot disconnects. Dismiss only hides the text you dismissed: a different error shows up again.
What stops a script
The text in the alert starts with where the failure happened:
| What happened | The text starts with |
|---|---|
| The top-level code of a module threw during the start | evaluate behavior module "library/my-first-script/1.0.0/index.js": |
The parameters or actions export isn't an object of objects, or an action has no run function |
read declarations of "library/my-first-script/1.0.0/index.js": |
| The entry function threw or rejected, or anything else failed before it returned | initialize behavior module "library/my-first-script/1.0.0/index.js": |
A handler registered with on() or onTraffic() threw |
Game traffic handler failed: |
A function you passed to on() or wait() to pick messages threw |
evaluate protocol handler selector: or evaluate protocol wait selector: |
An onChange() handler threw |
parameters.onChange handler followed by a number |
A promise rejected and nothing caught it, which includes an error thrown in an async handler or an async interceptor |
unhandled Promise rejection: |
The code that continued after an await went over the time limit |
drain JavaScript Promise jobs: |
A few failures have their own text, whichever of the beginnings above comes first:
| What happened | The text contains |
|---|---|
| A piece of code ran for more than 250 ms without awaiting | JavaScript execution deadline exceeded |
| The bot's queue filled up | behavior event-loop queue overflow |
| The game connection closed on its own | Game session closed |
The script called disconnect() |
behavior requested Game disconnect |
The default export has its own three errors, listed in The entry function.
Reading an error text
After the beginning comes the error itself.
An error your code threw shows as its type and message, such as Error: no zaap on this map or TypeError: gamedata.record id must be an integer. When it was thrown by a handler or a selector function that isn't async, at follows, with the file, the line and the column where it happened.
An error from an Asterobot function shows Asterobot's text. Promise rejected: in front of it means an await rejected. For example, sending token instead of ticketKey while the script starts gives:
initialize behavior module "library/my-first-script/1.0.0/index.js": Promise rejected: IdentificationRequest.token: unknown protobuf field
Error messages lists the texts of Asterobot's functions, with their causes.
What doesn't stop a script
| What happens | What you see instead |
|---|---|
An action button's run throws or rejects |
A toast named after the action, such as recall failed, with the error text. The script keeps running. |
An interceptor that isn't async throws, or returns a payload that can't be built |
That interceptor makes no decision: the next one is asked, and when none decides, the message goes through unchanged. The bot's console shows the error. An answer that comes after 50 ms is ignored without any report. An async interceptor never decides, and an error in it stops the script. See Intercepting. |
| A promise rejects and your code catches it | Whatever your catch does |
record() finds no record, or text() finds no text |
They return undefined. |
off() or offChange() receives a handler that's already removed |
Nothing |
The logging functions, botInfo() and the others, never throw.
Functions that throw right away
A few functions throw as soon as they're called, instead of returning a promise that rejects. A try/catch catches them without any await:
| Function | Throws when |
|---|---|
on(), onTraffic(), intercept(), onChange() |
The handler isn't a function, the selector is empty or neither a name nor a function, or 256 handlers are already registered: maximum behavior handlers reached. on(), onTraffic() and intercept() count together, and onChange() has its own 256. |
text() |
The key is neither a string nor a whole number |
record() |
The table name is empty, the id isn't a whole number, or the table doesn't exist |
packages.info() |
The name is empty, or matches no package the bot runs |
Keep a script running
A handful of habits prevent most failures, and every sample in these docs follows them:
- Put each
awaitof a handler insidetry/catch. An error that escapes a handler,asyncor not, stops the whole script. - Check that
traffic.payloadexists before reading its fields: a message Asterobot couldn't decode has no payload.traffic.payload?.contentchecks and reads at once. - Give every
wait()atimeout. Without one, a wait that never matches stays open until the script stops. Open the wait before you send what it answers, as Waiting shows. - When you start an
asyncfunction without awaiting it, catch its errors, inside it or where you start it:refreshLoop().catch((error) => botWarn("Loop stopped:", String(error)));. - Check what lookups return.
undefinedmeans nothing was found, or that the bot's game version has no game data. - Convert BigInt ids with
Number()before you pass them torecord()ortext(). - Log errors as
String(error). Logging and debugging explains why. - On a Full socket bot, make sure nothing after the identification can fail while the script starts. Otherwise the next start is
"initial"again, and the script identifies a second time.
This handler reads chat lines starting with !json and parses what follows. Without the try, anyone typing !json { in a channel your character reads would stop the script:
import { session, botInfo, botWarn } from "asterobot:bot";
import { on, send } from "asterobot:protocol";
export default async function behavior(launch) {
on("ChatChannelMessageEvent", (traffic) => {
const content = traffic.payload?.content;
if (!content?.startsWith("!json ")) return;
try {
const data = JSON.parse(content.slice(6));
botInfo("Parsed:", JSON.stringify(data));
} catch (error) {
// An error that escapes a handler stops the whole script.
botWarn("Not valid JSON:", String(error));
}
});
// A new game connection starts with this message. MITM bots never launch
// with "initial": the Dofus client has already identified their session.
if (launch.reason === "initial") {
await send("IdentificationRequest", {
ticketKey: session.gameToken,
languageCode: session.language,
});
}
}
Limits lists every limit and what happens past it. Next, Logging and debugging.
Aucun avis à afficher.