diff --git a/README.md b/README.md
index 2ca0c0a..0405aa7 100644
--- a/README.md
+++ b/README.md
@@ -111,6 +111,12 @@ You can also use `npx`:
```
+To specify a custom logger function, use `setTraceUnhandledLogger`:
+
+```ts
+window.setTraceUnhandledLogger( msg => { ... } ); // msg is a string
+```
+
## Programatically - API
@@ -127,6 +133,13 @@ const { register } = require( 'trace-unhandled' );
register( );
```
+To specify a custom logger function, use `setLogger`:
+
+```ts
+const { setLogger } = require( 'trace-unhandled' );
+setLogger( msg => { ... } ); // msg is a string
+```
+
## In unit tests
diff --git a/index.ts b/index.ts
index 72135ac..ded7f4c 100644
--- a/index.ts
+++ b/index.ts
@@ -1,2 +1,2 @@
-
+export { LoggerFunction, setLogger } from './lib/core';
export const register = ( ) => require( './lib/register' );
diff --git a/jest.config.js b/jest.config.js
index d47197d..9b630f9 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -2,4 +2,5 @@ module.exports = {
testEnvironment: "node",
testMatch: ['/test/**/*.spec.js'],
coverageReporters: ["lcov", "text", "html"],
+ coveragePathIgnorePatterns: [ '/node_modules/', '/test/' ],
};
diff --git a/lib/core.ts b/lib/core.ts
index aff9090..4f70dd5 100644
--- a/lib/core.ts
+++ b/lib/core.ts
@@ -54,6 +54,20 @@ function mergeErrors( traceError: Error, mainError?: Error )
errorLines.slice( 0, i ).reverse( ).join( "\n" );
}
+function defaultLogger( msg: string )
+{
+ console.error( msg );
+}
+
+export type LoggerFunction = ( msg: string ) => void;
+
+let loggerFunction: LoggerFunction = defaultLogger;
+
+export function setLogger( loggerFn: LoggerFunction )
+{
+ loggerFunction = loggerFn ?? defaultLogger;
+}
+
export function logger(
reason: Error | undefined,
promise: TraceablePromise< any >,
@@ -69,7 +83,7 @@ export function logger(
const prefix = pid == null ? '' : `(node:${pid}) `;
- console.error(
+ loggerFunction(
`${prefix}UnhandledPromiseRejectionWarning\n` +
(
!promise.__tracedError
diff --git a/test/helpers.js b/test/helpers.js
new file mode 100644
index 0000000..9d79bbd
--- /dev/null
+++ b/test/helpers.js
@@ -0,0 +1,41 @@
+const { Finally, Try, delay } = require( 'already' );
+
+module.exports.withConsoleSpy = fn => async ( ) =>
+{
+ const oldError = console.error;
+ console.error = jest.fn( );
+ return Try( fn )
+ .then( ...Finally( ( ) =>
+ {
+ console.error = oldError;
+ } ) );
+}
+
+module.exports.triggerUnhandledWarnings =
+ async function triggerUnhandledWarnings( )
+{
+ await delay( 0 );
+ global.gc && global.gc( );
+ await delay( 0 );
+}
+
+module.exports.splitLines = function splitLines( lines )
+{
+ return [ ].concat( ...lines.map( line => line.split( "\n" ) ) );
+}
+
+module.exports.cutColumn = function cutColumn( line )
+{
+ const m = line.match( /(.*:\d+):\d+\)?$/ );
+ if ( !m )
+ return line;
+ return m[ 1 ];
+}
+
+module.exports.cutLocation = function cutLocation( line )
+{
+ const m = line.match( /(.*):\d+:\d+\)?$/ );
+ if ( !m )
+ return line;
+ return m[ 1 ];
+}
diff --git a/test/logger.spec.js b/test/logger.spec.js
new file mode 100644
index 0000000..c90ec32
--- /dev/null
+++ b/test/logger.spec.js
@@ -0,0 +1,44 @@
+
+const index = require( '../dist/index' );
+const {
+ triggerUnhandledWarnings,
+ splitLines,
+ cutColumn,
+} = require( './helpers' );
+
+
+describe( "logger", ( ) =>
+{
+ it( "setLogger", async ( ) =>
+ {
+ const logger = jest.fn( );
+ index.setLogger( logger );
+ index.register( );
+
+ const err = new Error( "foobar" );
+
+ new Promise( ( resolve, reject ) =>
+ {
+ throw err;
+ } );
+
+ await triggerUnhandledWarnings( );
+
+ index.setLogger( );
+
+ const linesWoColumns = splitLines( logger.mock.calls[ 0 ] )
+ .filter( line => line.includes( "logger.spec.js" ) )
+ .map( line => cutColumn( line ) );
+
+ const errorAndShared = splitLines( logger.mock.calls[ 0 ] )
+ .filter( line => line );
+
+ expect( linesWoColumns.length ).toBeGreaterThanOrEqual( 2 );
+ expect( linesWoColumns[ 0 ] ).not.toBe( linesWoColumns[ 1 ] );
+
+ expect( errorAndShared )
+ .toContain( " ==== Error at: ====================" );
+ expect( errorAndShared )
+ .toContain( " ==== Shared trace: ================" );
+ } );
+} );
diff --git a/test/register.spec.js b/test/register.spec.js
index 817df49..da98921 100644
--- a/test/register.spec.js
+++ b/test/register.spec.js
@@ -1,45 +1,14 @@
-const { Finally, Try, delay } = require( 'already' );
-require( '../register' );
-
-const withConsoleSpy = fn => async ( ) =>
-{
- const oldError = console.error;
- console.error = jest.fn( );
- return Try( fn )
- .then( ...Finally( ( ) =>
- {
- console.error = oldError;
- } ) );
-}
+const {
+ withConsoleSpy,
+ triggerUnhandledWarnings,
+ splitLines,
+ cutColumn,
+ cutLocation,
+} = require( './helpers' );
-async function triggerUnhandledWarnings( )
-{
- await delay( 0 );
- global.gc && global.gc( );
- await delay( 0 );
-}
-
-function splitLines( lines )
-{
- return [ ].concat( ...lines.map( line => line.split( "\n" ) ) );
-}
-
-function cutColumn( line )
-{
- const m = line.match( /(.*:\d+):\d+\)?$/ );
- if ( !m )
- return line;
- return m[ 1 ];
-}
+require( '../register' );
-function cutLocation( line )
-{
- const m = line.match( /(.*):\d+:\d+\)?$/ );
- if ( !m )
- return line;
- return m[ 1 ];
-}
describe( "register", ( ) =>
{
@@ -151,7 +120,7 @@ describe( "register", ( ) =>
const errorAndShared = splitLines( console.error.mock.calls[ 0 ] )
.filter( line => line );
- expect( linesWoColumns.length ).toBeGreaterThanOrEqual( 2 );
+ expect( linesWoColumns.length ).toBeGreaterThanOrEqual( 1 );
expect( linesWoColumns[ 0 ] ).not.toBe( linesWoColumns[ 1 ] );
expect( errorAndShared[ errorAndShared.length - 2 ] ).toBe(
@@ -180,7 +149,7 @@ describe( "register", ( ) =>
const errorAndShared = splitLines( console.error.mock.calls[ 0 ] )
.filter( line => line );
- expect( linesWoColumns.length ).toBeGreaterThanOrEqual( 2 );
+ expect( linesWoColumns.length ).toBeGreaterThanOrEqual( 1 );
expect( linesWoColumns[ 0 ] ).not.toBe( linesWoColumns[ 1 ] );
expect( errorAndShared[ errorAndShared.length - 2 ] ).toBe(
diff --git a/web/register-web.ts b/web/register-web.ts
index 61bd713..7ec658b 100644
--- a/web/register-web.ts
+++ b/web/register-web.ts
@@ -1,5 +1,5 @@
-import { logger, TraceablePromise } from "../lib/core";
+import { logger, TraceablePromise, setLogger} from "../lib/core";
window.onunhandledrejection = function( event: PromiseRejectionEvent )
{
@@ -7,3 +7,4 @@ window.onunhandledrejection = function( event: PromiseRejectionEvent )
};
( < any >window ).Promise = TraceablePromise;
+( < any >window ).setTraceUnhandledLogger = setLogger;