2
0
Kaynağa Gözat

Fixes #897

Do not handle signaled exceptions twice in Helios (or any other
connected Amber environment).
Nicolas Petton 10 yıl önce
ebeveyn
işleme
6d4a117f18

+ 2 - 9
src/Helios-Debugger.js

@@ -894,20 +894,13 @@ fn: function (anError){
 var self=this;
 function $AIContext(){return globals.AIContext||(typeof AIContext=="undefined"?nil:AIContext)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
 self["@error"]=anError;
-_st(console)._log_(self["@error"]);
-$ctx1.sendIdx["log:"]=1;
-$1=console;
-$2=_st(self["@error"])._context();
-$ctx1.sendIdx["context"]=1;
-_st($1)._log_($2);
 self["@rootContext"]=_st($AIContext())._fromMethodContext_(_st(self["@error"])._context());
 self._initializeContexts();
 return self}, function($ctx1) {$ctx1.fill(self,"initializeFromError:",{anError:anError},globals.HLDebuggerModel)})},
 args: ["anError"],
-source: "initializeFromError: anError\x0a\x09error := anError.\x0a\x09console log: error.\x0a\x09console log: error context.\x0a\x09rootContext := (AIContext fromMethodContext: error context).\x0a\x09self initializeContexts",
-messageSends: ["log:", "context", "fromMethodContext:", "initializeContexts"],
+source: "initializeFromError: anError\x0a\x09error := anError.\x0a\x09rootContext := (AIContext fromMethodContext: error context).\x0a\x09self initializeContexts",
+messageSends: ["fromMethodContext:", "context", "initializeContexts"],
 referencedClasses: ["AIContext"]
 }),
 globals.HLDebuggerModel);

+ 0 - 2
src/Helios-Debugger.st

@@ -368,8 +368,6 @@ initializeFromContext: aMethodContext
 
 initializeFromError: anError
 	error := anError.
-	console log: error.
-	console log: error context.
 	rootContext := (AIContext fromMethodContext: error context).
 	self initializeContexts
 ! !

+ 59 - 4
src/Kernel-Exceptions.js

@@ -4,6 +4,38 @@ smalltalk.packages["Kernel-Exceptions"].transport = {"type":"amd","amdNamespace"
 
 smalltalk.addClass('Error', globals.Object, ['messageText'], 'Kernel-Exceptions');
 globals.Error.comment="From the ANSI standard:\x0a\x0aThis protocol describes the behavior of instances of class `Error`.\x0aThese are used to represent error conditions that prevent the normal continuation of processing.\x0aActual error exceptions used by an application may be subclasses of this class.\x0aAs `Error` is explicitly specified to be subclassable, conforming implementations must implement its behavior in a non-fragile manner.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "beHandled",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self.amberHandled = true;
+return self}, function($ctx1) {$ctx1.fill(self,"beHandled",{},globals.Error)})},
+args: [],
+source: "beHandled\x0a\x09<self.amberHandled = true>",
+messageSends: [],
+referencedClasses: []
+}),
+globals.Error);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "beUnhandled",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self.amberHandled = false;
+return self}, function($ctx1) {$ctx1.fill(self,"beUnhandled",{},globals.Error)})},
+args: [],
+source: "beUnhandled\x0a\x09<self.amberHandled = false>",
+messageSends: [],
+referencedClasses: []
+}),
+globals.Error);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "context",
@@ -107,10 +139,13 @@ protocol: 'signaling',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-throw(self);
+
+		self.amberHandled = false;
+		throw(self);
+	;
 return self}, function($ctx1) {$ctx1.fill(self,"resignal",{},globals.Error)})},
 args: [],
-source: "resignal\x0a\x09\x22Resignal the receiver without changing its exception context\x22\x0a\x09\x0a\x09<throw(self)>",
+source: "resignal\x0a\x09\x22Resignal the receiver without changing its exception context\x22\x0a\x09\x0a\x09<\x0a\x09\x09self.amberHandled = false;\x0a\x09\x09throw(self);\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -123,10 +158,14 @@ protocol: 'signaling',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self);
+
+		self.amberHandled = false;
+		self.context = smalltalk.getThisContext(); 
+		self.smalltalkError = true; throw(self)
+	;
 return self}, function($ctx1) {$ctx1.fill(self,"signal",{},globals.Error)})},
 args: [],
-source: "signal\x0a\x09<self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self)>",
+source: "signal\x0a\x09<\x0a\x09\x09self.amberHandled = false;\x0a\x09\x09self.context = smalltalk.getThisContext(); \x0a\x09\x09self.smalltalkError = true; throw(self)\x0a\x09>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -149,6 +188,22 @@ referencedClasses: []
 }),
 globals.Error);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "wasHandled",
+protocol: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self.amberHandled || false;
+return self}, function($ctx1) {$ctx1.fill(self,"wasHandled",{},globals.Error)})},
+args: [],
+source: "wasHandled\x0a\x09<return self.amberHandled || false>",
+messageSends: [],
+referencedClasses: []
+}),
+globals.Error);
+
 
 smalltalk.addMethod(
 smalltalk.method({

+ 21 - 2
src/Kernel-Exceptions.st

@@ -12,6 +12,14 @@ As `Error` is explicitly specified to be subclassable, conforming implementation
 
 !Error methodsFor: 'accessing'!
 
+beHandled
+	<self.amberHandled = true>
+!
+
+beUnhandled
+	<self.amberHandled = false>
+!
+
 context
 	<return self.context>
 !
@@ -39,11 +47,18 @@ initialize
 resignal
 	"Resignal the receiver without changing its exception context"
 	
-	<throw(self)>
+	<
+		self.amberHandled = false;
+		throw(self);
+	>
 !
 
 signal
-	<self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self)>
+	<
+		self.amberHandled = false;
+		self.context = smalltalk.getThisContext(); 
+		self.smalltalkError = true; throw(self)
+	>
 !
 
 signal: aString
@@ -55,6 +70,10 @@ signal: aString
 
 isSmalltalkError
 	<return self.smalltalkError === true>
+!
+
+wasHandled
+	<return self.amberHandled || false>
 ! !
 
 !Error class methodsFor: 'helios'!

+ 25 - 3
src/Kernel-Infrastructure.js

@@ -2216,11 +2216,33 @@ protocol: 'error handling',
 fn: function (anError){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(self._current())._handleError_(anError);
+self._handleUnhandledError_(anError);
 return self}, function($ctx1) {$ctx1.fill(self,"handleError:",{anError:anError},globals.ErrorHandler.klass)})},
 args: ["anError"],
-source: "handleError: anError\x0a\x09self current handleError: anError",
-messageSends: ["handleError:", "current"],
+source: "handleError: anError\x0a\x09self handleUnhandledError: anError",
+messageSends: ["handleUnhandledError:"],
+referencedClasses: []
+}),
+globals.ErrorHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "handleUnhandledError:",
+protocol: 'error handling',
+fn: function (anError){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(anError)._wasHandled();
+if(smalltalk.assert($1)){
+return self;
+};
+$2=_st(self._current())._handleError_(anError);
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"handleUnhandledError:",{anError:anError},globals.ErrorHandler.klass)})},
+args: ["anError"],
+source: "handleUnhandledError: anError\x0a\x09anError wasHandled ifTrue: [ ^ self ].\x0a\x09\x0a\x09^ self current handleError: anError",
+messageSends: ["ifTrue:", "wasHandled", "handleError:", "current"],
 referencedClasses: []
 }),
 globals.ErrorHandler.klass);

+ 7 - 1
src/Kernel-Infrastructure.st

@@ -843,7 +843,13 @@ Registered service instances must implement `#handleError:` to perform an action
 !ErrorHandler class methodsFor: 'error handling'!
 
 handleError: anError
-	self current handleError: anError
+	self handleUnhandledError: anError
+!
+
+handleUnhandledError: anError
+	anError wasHandled ifTrue: [ ^ self ].
+	
+	^ self current handleError: anError
 ! !
 
 Service subclass: #Finder

+ 1 - 0
support/boot.js

@@ -882,6 +882,7 @@ define("amber_vm/boot", [ 'require', './browser-compatibility' ], function (requ
 					handleError(error);
 					st.thisContext = null;
 					// Rethrow the error in any case.
+					error.amberHandled = true;
 					throw error;
 				}
 			}