Skip to content

Commit 21e9903

Browse files
authored
Merge pull request #4 from gregario/fix/improve-error-messages
fix: improve error messages in claimWork and heartbeat
2 parents 65e1194 + dd7ff95 commit 21e9903

2 files changed

Lines changed: 22 additions & 8 deletions

File tree

src/db/queries.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,17 @@ export async function claimWork(params: ClaimWorkParams): Promise<{ claim: Claim
257257
const intentRes = await query<Intent>(`SELECT * FROM intents WHERE id = $1`, [params.intent_id]);
258258
const intent = intentRes.rows[0];
259259
if (!intent) throw new Error(`Intent ${params.intent_id} not found`);
260-
if (intent.status !== 'open') throw new Error(`Intent ${params.intent_id} is not open (current: ${intent.status})`);
260+
if (intent.status !== 'open') {
261+
if (intent.status === 'claimed') {
262+
const activeClaim = await query<Claim>(
263+
`SELECT claimed_by FROM claims WHERE intent_id = $1 AND status = 'active' LIMIT 1`,
264+
[params.intent_id]
265+
);
266+
const claimedBy = activeClaim.rows[0]?.claimed_by;
267+
throw new Error(`Intent ${params.intent_id} is already claimed by ${claimedBy ?? 'unknown'}`);
268+
}
269+
throw new Error(`Intent ${params.intent_id} is not open (current: ${intent.status})`);
270+
}
261271

262272
// Create the claim
263273
const claimRes = await query<Claim>(
@@ -299,7 +309,11 @@ export async function heartbeat(claimId: string, filesTouching?: string[]): Prom
299309
`UPDATE claims SET ${sets.join(', ')} WHERE id = $${paramIdx} AND status = 'active' RETURNING *`,
300310
[...values, claimId]
301311
);
302-
if (res.rows.length === 0) throw new Error(`Active claim ${claimId} not found`);
312+
if (res.rows.length === 0) {
313+
const existing = await query<Claim>(`SELECT status FROM claims WHERE id = $1`, [claimId]);
314+
if (existing.rows.length === 0) throw new Error(`Claim ${claimId} not found`);
315+
throw new Error(`Claim ${claimId} is not active (current: ${existing.rows[0].status})`);
316+
}
303317
return res.rows[0];
304318
}
305319

tests/edge-cases.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,13 @@ describe('Edge Cases & Error Paths', () => {
6262
).rejects.toThrow('not found');
6363
});
6464

65-
it('claim rejects already-claimed intent', async () => {
65+
it('claim rejects already-claimed intent with claimer info', async () => {
6666
const intent = await seedOpenIntent();
6767
await db.claimWork({ intent_id: intent.id as string, claimed_by: 'pawel' });
6868

6969
await expect(
7070
db.claimWork({ intent_id: intent.id as string, claimed_by: 'alice' })
71-
).rejects.toThrow('not open');
71+
).rejects.toThrow('claimed by pawel');
7272
});
7373

7474
it('claim rejects done intent', async () => {
@@ -90,15 +90,15 @@ describe('Edge Cases & Error Paths', () => {
9090
const { claim } = await db.claimWork({ intent_id: intent.id as string, claimed_by: 'pawel' });
9191
await db.completeClaim(claim.id);
9292

93-
await expect(db.completeClaim(claim.id)).rejects.toThrow('not active');
93+
await expect(db.completeClaim(claim.id)).rejects.toThrow('completed');
9494
});
9595

9696
it('complete rejects abandoned claim', async () => {
9797
const intent = await seedOpenIntent();
9898
const { claim } = await db.claimWork({ intent_id: intent.id as string, claimed_by: 'pawel' });
9999
await db.releaseClaim(claim.id);
100100

101-
await expect(db.completeClaim(claim.id)).rejects.toThrow('not active');
101+
await expect(db.completeClaim(claim.id)).rejects.toThrow('abandoned');
102102
});
103103

104104
it('release rejects non-existent claim', async () => {
@@ -109,12 +109,12 @@ describe('Edge Cases & Error Paths', () => {
109109
await expect(db.heartbeat('claim_nonexistent')).rejects.toThrow('not found');
110110
});
111111

112-
it('heartbeat rejects completed claim', async () => {
112+
it('heartbeat rejects completed claim with status', async () => {
113113
const intent = await seedOpenIntent();
114114
const { claim } = await db.claimWork({ intent_id: intent.id as string, claimed_by: 'pawel' });
115115
await db.completeClaim(claim.id);
116116

117-
await expect(db.heartbeat(claim.id)).rejects.toThrow('not found');
117+
await expect(db.heartbeat(claim.id)).rejects.toThrow('completed');
118118
});
119119

120120
// ─── Conflict Edge Cases ────────────────────────

0 commit comments

Comments
 (0)