crash-recovery.integration.test.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // Integration test for CLAUDE.md §7.4 — when the isolate dies mid-invoke
  2. // (Deno.exit, segfault, panic) the host must surface `isolate_crashed`
  3. // promptly rather than waiting the full invocation timeout. Also verifies
  4. // that uncaught customer errors get tagged `function_threw` with their
  5. // message preserved (sanitizer is host-side only).
  6. import { describe, expect, test } from 'bun:test';
  7. import { runIntegrationFixture } from './test-helpers.js';
  8. describe('crash recovery (integration)', () => {
  9. test('Deno.exit during invoke surfaces isolate_crashed', async () => {
  10. const { result, cleanup } = await runIntegrationFixture({
  11. fnName: 'test',
  12. deploymentId: 'd1',
  13. fnSource: `
  14. import { query } from '@briven/cli/server';
  15. export const test = query(async () => {
  16. Deno.exit(7);
  17. });
  18. `,
  19. });
  20. try {
  21. expect(result.ok).toBe(false);
  22. if (!result.ok) {
  23. // Drain-on-exit (Task 11) should surface isolate_crashed promptly.
  24. // Accept invocation_timeout as a fallback in case the resolver
  25. // hasn't been drained by the time we sample.
  26. expect(['isolate_crashed', 'invocation_timeout']).toContain(result.code);
  27. }
  28. } finally {
  29. await cleanup();
  30. }
  31. }, 30_000);
  32. test('thrown error surfaces function_threw with sanitized message', async () => {
  33. const { result, cleanup } = await runIntegrationFixture({
  34. fnName: 'test',
  35. deploymentId: 'd1',
  36. fnSource: `
  37. import { query } from '@briven/cli/server';
  38. export const test = query(async () => {
  39. throw new Error('boom from /tmp/briven-isolate-fake-leak');
  40. });
  41. `,
  42. });
  43. try {
  44. expect(result.ok).toBe(false);
  45. if (!result.ok) {
  46. expect(result.code).toBe('function_threw');
  47. expect(result.message).toContain('boom');
  48. // Sanitizer should NOT have stripped /tmp/briven-isolate-fake-leak from
  49. // INSIDE the customer's own message body — that would over-redact. The
  50. // sanitizer applies to host-side error paths only. So this assertion
  51. // is intentionally not strict on path content.
  52. }
  53. } finally {
  54. await cleanup();
  55. }
  56. }, 30_000);
  57. });