Problem: Bridge Callback and Promise APIs
Problem statement
Your system relies on a legacy database client that still uses Node.js-style callbacks:
db.query('SELECT * FROM users', (err, result) => { ... });
Modern code in your app, however, uses async/await everywhere. Mixing both styles leads to nested callback chains and inconsistent code. You’ve been asked to create an adapter that wraps the legacy client so that all queries can be awaited, without modifying the client itself.
Goal
Implement a DbClientAdapter class that wraps a callback-based client and exposes a promise-based method:
async query(sql)
Internally, it should call the original callback-style API.
Externally, it should return a promise that resolves or rejects based on the callback outcome.
Constraints
You cannot modify the legacy client.
You must convert the callback API to a promise-based interface using standard Node.js techniques.
Do not use external libraries (
util.promisifyis allowed but optional).The adapter should behave exactly like a native promise-based client.
Sample output
The examples below illustrate what the output should look like:
(async () => {const db = new DbClientAdapter(legacyDb);try {const users = await db.query('SELECT * FROM users');console.log(users);} catch (err) {console.error('Error:', err.message);}/* Expected output:[ 'Result of "SELECT * FROM users"' ] */try {await db.query('SELECT * FROM error');} catch (err) {console.error('Error:', err.message);}/* Expected output:Error: Query failed */})();
Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.
Problem: Bridge Callback and Promise APIs
Problem statement
Your system relies on a legacy database client that still uses Node.js-style callbacks:
db.query('SELECT * FROM users', (err, result) => { ... });
Modern code in your app, however, uses async/await everywhere. Mixing both styles leads to nested callback chains and inconsistent code. You’ve been asked to create an adapter that wraps the legacy client so that all queries can be awaited, without modifying the client itself.
Goal
Implement a DbClientAdapter class that wraps a callback-based client and exposes a promise-based method:
async query(sql)
Internally, it should call the original callback-style API.
Externally, it should return a promise that resolves or rejects based on the callback outcome.
Constraints
You cannot modify the legacy client.
You must convert the callback API to a promise-based interface using standard Node.js techniques.
Do not use external libraries (
util.promisifyis allowed but optional).The adapter should behave exactly like a native promise-based client.
Sample output
The examples below illustrate what the output should look like:
(async () => {const db = new DbClientAdapter(legacyDb);try {const users = await db.query('SELECT * FROM users');console.log(users);} catch (err) {console.error('Error:', err.message);}/* Expected output:[ 'Result of "SELECT * FROM users"' ] */try {await db.query('SELECT * FROM error');} catch (err) {console.error('Error:', err.message);}/* Expected output:Error: Query failed */})();
Good luck trying the problem! If you’re unsure how to proceed, check the “Solution” tab above.