Prefer error_code when present and route projectMembers/freeformDoc/ taskRuns/chatSessions failures through the shared structured parser. Co-authored-by: Cursor <cursoragent@cursor.com>
52 lines
2.0 KiB
TypeScript
52 lines
2.0 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { addProjectMember, updateProjectMember } from './projectMembers';
|
|
import { ProjectSettingsApiError } from './projectSettingsError';
|
|
|
|
test('addProjectMember exposes structured ProjectSettingsApiError on 403', async () => {
|
|
const originalFetch = globalThis.fetch;
|
|
globalThis.fetch = async () =>
|
|
new Response(JSON.stringify({ code: 'AUTHZ', message: '无权访问', error: 'ERR_FORBIDDEN' }), {
|
|
status: 403,
|
|
headers: { 'Content-Type': 'application/json' },
|
|
});
|
|
try {
|
|
await assert.rejects(
|
|
() => addProjectMember(143, { user_id: 2, project_role: 'member' }),
|
|
(err: unknown) => {
|
|
assert.ok(err instanceof ProjectSettingsApiError);
|
|
assert.equal((err as ProjectSettingsApiError).status, 403);
|
|
// Envelope code wins over bare error string in the shared parser.
|
|
assert.equal((err as ProjectSettingsApiError).code, 'AUTHZ');
|
|
assert.equal((err as ProjectSettingsApiError).message, '无权访问');
|
|
return true;
|
|
},
|
|
);
|
|
} finally {
|
|
globalThis.fetch = originalFetch;
|
|
}
|
|
});
|
|
|
|
test('updateProjectMember surfaces safe INTERNAL message on 500 duty-sync failure', async () => {
|
|
const originalFetch = globalThis.fetch;
|
|
globalThis.fetch = async () =>
|
|
new Response(
|
|
JSON.stringify({ code: 'INTERNAL', message: '请求无法完成', error: 'ERR_DUTY_SYNC' }),
|
|
{ status: 500, headers: { 'Content-Type': 'application/json' } },
|
|
);
|
|
try {
|
|
await assert.rejects(
|
|
() => updateProjectMember(143, { user_id: 2, project_role: 'member' }),
|
|
(err: unknown) => {
|
|
assert.ok(err instanceof ProjectSettingsApiError);
|
|
assert.equal((err as ProjectSettingsApiError).status, 500);
|
|
assert.equal((err as ProjectSettingsApiError).code, 'INTERNAL');
|
|
assert.equal((err as ProjectSettingsApiError).message, '请求无法完成');
|
|
return true;
|
|
},
|
|
);
|
|
} finally {
|
|
globalThis.fetch = originalFetch;
|
|
}
|
|
});
|