Scripts
A cron's entry point is cronhoster-cron-handler.js, an ordinary Node script at the top of the
cron directory. When a run matches the current second, the runner starts the
handler as a fresh Node process, with the cron directory as its working directory, and passes the matched
time on the command line. There is no framework to import, no ctx object, and no required
module.exports. The handler is just a script that reads process.argv and does its
work.
Command-line arguments
The runner spawns the handler with the cron name, the name of the run that matched, and the six matched time fields, in this order:
node cronhoster-cron-handler.js <cron> <run> <year> <month> <day> <hour> <minute> <second>
| Position | Name | Meaning |
|---|---|---|
argv[2] | cron | The cron name, which is the directory name. |
argv[3] | run | The name of the run that matched. |
argv[4] | year | Matched UTC year. |
argv[5] | month | Matched UTC month, 1 to 12. |
argv[6] | day | Matched UTC day of month, 1 to 31. |
argv[7] | hour | Matched UTC hour, 0 to 23. |
argv[8] | minute | Matched UTC minute, 0 to 59. |
argv[9] | second | Matched UTC second, 0 to 59. |
An example handler
A handler destructures process.argv.slice(2) and does its work. Whatever it writes to
stdout and stderr is captured for the Cron Logs tool:
const [cron, run, year, month, day, hour, minute, second] = process.argv.slice(2);
console.log(`${cron}/${run} fired at ${year}-${month}-${day} ${hour}:${minute}:${second} UTC`);
Success and failure
A run succeeds when its process exits with code 0. A run
fails when the process exits with any non-zero code, or when the handler throws and the
process exits non-zero as a result. Either way the run is recorded with its start time, duration, exit
code, and the captured stdout and stderr.
A failure never retries. It never blocks the next run beyond the cron's concurrency ceiling: the next
matching time starts a fresh process as usual, up to
cronhoster-cron-setting-maxConcurrent handlers running at once. Read the records in the
Cron Logs tool to see what happened.
Bundled modules and resolution
Only cronhoster-cron-handler.js is run. Anything else inside the cron directory is a module
the handler imports, uploaded as part of the cron, and never run on its own. Because the process starts
with the cron directory as its working directory, require and import resolve
from there: a relative path resolves against the importing file, and a node_modules folder
inside the cron is honoured. A cron carries its own copy of everything it needs, so it is self-contained
and nothing resolves across cron boundaries.
const { format } = require('./format');
const { send } = require('./mailer');
async function main() {
const [cron, run] = process.argv.slice(2);
await send(format(await gather()));
}
main();
See the Files reference for which paths are crons, which are the modules inside them, and which are ignored. The schedule that decides when a handler runs lives in the cron's settings, and the day-to-day workflow is in Usage.