test-uncaught-exception-from-handler.ts 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import Piscina from '..';
  2. import { test } from 'tap';
  3. import { resolve } from 'path';
  4. import { once } from 'events';
  5. test('uncaught exception resets Worker', async ({ rejects }) => {
  6. const pool = new Piscina({
  7. filename: resolve(__dirname, 'fixtures/eval.js')
  8. });
  9. await rejects(pool.runTask('throw new Error("not_caught")'), /not_caught/);
  10. });
  11. test('uncaught exception in immediate resets Worker', async ({ rejects }) => {
  12. const pool = new Piscina({
  13. filename: resolve(__dirname, 'fixtures/eval.js')
  14. });
  15. await rejects(
  16. pool.runTask(`
  17. setImmediate(() => { throw new Error("not_caught") });
  18. new Promise(() => {}) /* act as if we were doing some work */
  19. `), /not_caught/);
  20. });
  21. test('uncaught exception in immediate after task yields error event', async ({ equal }) => {
  22. const pool = new Piscina({
  23. filename: resolve(__dirname, 'fixtures/eval.js'),
  24. maxThreads: 1,
  25. useAtomics: false
  26. });
  27. const errorEvent : Promise<Error[]> = once(pool, 'error');
  28. const taskResult = pool.runTask(`
  29. setTimeout(() => { throw new Error("not_caught") }, 500);
  30. 42
  31. `);
  32. equal(await taskResult, 42);
  33. // Hack a bit to make sure we get the 'exit'/'error' events.
  34. equal(pool.threads.length, 1);
  35. pool.threads[0].ref();
  36. // This is the main assertion here.
  37. equal((await errorEvent)[0].message, 'not_caught');
  38. });
  39. test('exiting process resets worker', async ({ not, rejects }) => {
  40. const pool = new Piscina({
  41. filename: resolve(__dirname, 'fixtures/eval.js'),
  42. minThreads: 1
  43. });
  44. const originalThreadId = pool.threads[0].threadId;
  45. await rejects(pool.runTask('process.exit(1);'), /worker exited with code: 1/);
  46. const newThreadId = pool.threads[0].threadId;
  47. not(originalThreadId, newThreadId);
  48. });
  49. test('exiting process in immediate after task errors next task and resets worker', async ({ equal, not, rejects }) => {
  50. const pool = new Piscina({
  51. filename: resolve(__dirname, 'fixtures/eval-async.js'),
  52. minThreads: 1
  53. });
  54. const originalThreadId = pool.threads[0].threadId;
  55. const taskResult = await pool.runTask(`
  56. setTimeout(() => { process.exit(1); }, 50);
  57. 42
  58. `);
  59. equal(taskResult, 42);
  60. await rejects(pool.runTask(`
  61. 'use strict';
  62. const { promisify } = require('util');
  63. const sleep = promisify(setTimeout);
  64. async function _() {
  65. await sleep(1000);
  66. return 42
  67. }
  68. _();
  69. `), /worker exited with code: 1/);
  70. const secondThreadId = pool.threads[0].threadId;
  71. not(originalThreadId, secondThreadId);
  72. });