Fix the lint check for promises nobody awaits
Your task
A Node.js webhook handler charges a customer, then records the charge. Its line chargeCustomer(customerId, amount); // returns a Promise has no await. So a failed charge never reaches the try/catch, and the row still says ok. The team wants a lint check for floating promises: calls to an async function whose promise nobody awaits, chains or returns.
An assistant wrote find_floating_promises(body_lines, async_functions). It is in the editor. It has a bug. Find it and fix it.
Input and output:
body_lines: the lines of a function body, in order. A line can have spaces or tabs at either end. The list can be empty.async_functions: the names of the functions that return a promise, such as"chargeCustomer"or"db.insert". Ignore an empty name. The list can be empty.- Return the numbers of the lines that hold a floating promise, as a list of integers.
Rules the tests check:
- Lines are numbered from 1, and every line counts, blank ones and comments included.
- Trim spaces and tabs at both ends of each line. Every check below reads the whole trimmed line, including any comment at its end and any text in quotes.
- Skip a line that is empty after trimming or that starts with
//. Only a line that starts with//is a comment. Code before a//still counts. - A line calls a name when the name appears in it followed directly by
(. The character just before the name must not be a letter (a to z or A to Z), a digit,_or$. A name at the start of the line has no character before it, so it counts. One such place in the line is enough. - So
recharge(does not callcharge, butx.charge(does.charge (with a space does not. - Names are case sensitive.
- Skip a line that calls none of the names.
- A line that calls a name is still fine in any of these cases:
- It contains the text
awaitanywhere, even inside a longer word or a comment. - It contains
.then(or.catch(anywhere. - It starts with
returnfollowed by a space.
- It contains the text
- Every other line that calls a name holds a floating promise. Add its number once, even when it calls several names.
- Return the line numbers in ascending order. Return an empty list when no line is flagged.
Examples
find_floating_promises(body_lines: list[str], async_functions: list[str]) -> list[int]Example 1
Input
find_floating_promises(["const { customerId, amount } = req.body;", "chargeCustomer(customerId, amount);", "await db.insert('charges', { customerId, amount, status: 'ok' });", "res.status(200).json({ ok: true });"], ["chargeCustomer", "db.insert"])Output
[2]Example 2
Input
find_floating_promises(["await chargeCustomer(customerId, amount);", "await db.insert('charges', { status: 'ok' });"], ["chargeCustomer", "db.insert"])Output
[]