From 4dfe84106f7fc3761744a582e71a80e7fd2a75b1 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 28 May 2019 05:26:17 -0500 Subject: [PATCH 1/3] wip allow raises-exception --- packages/outputarea/src/widget.ts | 10 +++++++++- tests/test-outputarea/src/widget.spec.ts | 25 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/packages/outputarea/src/widget.ts b/packages/outputarea/src/widget.ts index 0b04ae2b185f..24866a21c59f 100644 --- a/packages/outputarea/src/widget.ts +++ b/packages/outputarea/src/widget.ts @@ -535,9 +535,17 @@ export namespace OutputArea { metadata?: JSONObject ): Promise { // Override the default for `stop_on_error`. + let stopOnError = true; + if ( + metadata && + metadata.tags && + (metadata.tags as string[]).indexOf('raises-exception') !== -1 + ) { + stopOnError = false; + } let content: KernelMessage.IExecuteRequest = { code, - stop_on_error: true + stop_on_error: stopOnError }; if (!session.kernel) { diff --git a/tests/test-outputarea/src/widget.spec.ts b/tests/test-outputarea/src/widget.spec.ts index a9dc910b27c3..9d0866a92970 100644 --- a/tests/test-outputarea/src/widget.spec.ts +++ b/tests/test-outputarea/src/widget.spec.ts @@ -257,6 +257,31 @@ describe('outputarea/widget', () => { expect(outputs[2].data).to.deep.equal({ 'text/plain': '4' }); await ipySession.shutdown(); }); + + it('should raise an error', async () => { + const widget1 = new LogOutputArea({ rendermime, model }); + const reply = await OutputArea.execute('a++1', widget, session); + const reply2 = await OutputArea.execute('a=1', widget1, session); + expect(reply.content.status).to.equal('hi'); + expect(reply2.content.status).to.equal('hi'); + expect(model.length).to.equal(1); + widget1.dispose(); + }); + + it('should allow an error given "raises-exception" metadata tag', async () => { + const widget1 = new LogOutputArea({ rendermime, model }); + const metadata = { tags: ['raises-exception'] }; + const reply = await OutputArea.execute( + 'a++1', + widget, + session, + metadata + ); + const reply2 = await OutputArea.execute('a=1', widget1, session); + expect(reply.content.execution_count).to.equal('hi'); + expect(reply2.content.execution_count).to.equal('hi'); + widget1.dispose(); + }); }); describe('.ContentFactory', () => { From bf4e0f7471c696678996269c5cecabe3bdec1e88 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Tue, 28 May 2019 06:07:18 -0500 Subject: [PATCH 2/3] update tests --- tests/test-outputarea/src/widget.spec.ts | 38 +++++++++++++++++------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/tests/test-outputarea/src/widget.spec.ts b/tests/test-outputarea/src/widget.spec.ts index 9d0866a92970..7da4b1b2ffab 100644 --- a/tests/test-outputarea/src/widget.spec.ts +++ b/tests/test-outputarea/src/widget.spec.ts @@ -258,29 +258,47 @@ describe('outputarea/widget', () => { await ipySession.shutdown(); }); - it('should raise an error', async () => { + it('should stop on an error', async () => { + let ipySession: ClientSession; + ipySession = await createClientSession({ + kernelPreference: { name: 'ipython' } + }); + await ipySession.initialize(); + await ipySession.kernel.ready; const widget1 = new LogOutputArea({ rendermime, model }); - const reply = await OutputArea.execute('a++1', widget, session); - const reply2 = await OutputArea.execute('a=1', widget1, session); - expect(reply.content.status).to.equal('hi'); - expect(reply2.content.status).to.equal('hi'); + const future1 = OutputArea.execute('a++1', widget, ipySession); + const future2 = OutputArea.execute('a=1', widget1, ipySession); + const reply = await future1; + const reply2 = await future2; + expect(reply.content.status).to.equal('error'); + expect(reply2.content.status).to.equal('aborted'); expect(model.length).to.equal(1); widget1.dispose(); + await ipySession.shutdown(); }); it('should allow an error given "raises-exception" metadata tag', async () => { + let ipySession: ClientSession; + ipySession = await createClientSession({ + kernelPreference: { name: 'ipython' } + }); + await ipySession.initialize(); + await ipySession.kernel.ready; const widget1 = new LogOutputArea({ rendermime, model }); const metadata = { tags: ['raises-exception'] }; - const reply = await OutputArea.execute( + const future1 = OutputArea.execute( 'a++1', widget, - session, + ipySession, metadata ); - const reply2 = await OutputArea.execute('a=1', widget1, session); - expect(reply.content.execution_count).to.equal('hi'); - expect(reply2.content.execution_count).to.equal('hi'); + const future2 = OutputArea.execute('a=1', widget1, ipySession); + const reply = await future1; + const reply2 = await future2; + expect(reply.content.status).to.equal('error'); + expect(reply2.content.status).to.equal('ok'); widget1.dispose(); + await ipySession.shutdown(); }); }); From 6d968b1773681d2f14b93323c0fe03cb723f2a0d Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 29 May 2019 02:23:53 -0500 Subject: [PATCH 3/3] cleanup logic --- packages/outputarea/src/widget.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/outputarea/src/widget.ts b/packages/outputarea/src/widget.ts index 24866a21c59f..225afecd75f6 100644 --- a/packages/outputarea/src/widget.ts +++ b/packages/outputarea/src/widget.ts @@ -538,8 +538,8 @@ export namespace OutputArea { let stopOnError = true; if ( metadata && - metadata.tags && - (metadata.tags as string[]).indexOf('raises-exception') !== -1 + Array.isArray(metadata.tags) && + metadata.tags.indexOf('raises-exception') !== -1 ) { stopOnError = false; }