Jump to content
Der schöne Günther

Is it possible to raise an aggregated exception?

Recommended Posts

Consider the following:

  1. I have a method that raises an EAggregateException that only contains one inner exception
  2. In my try block, I would like to extract the one inner exception and raise this instead.

 

procedure raiseAggregate();
var
	innerExceptions:	TArray<Exception>;
	aggregateException:	EAggregateException;
begin
	innerExceptions := [EProgrammerNotFound.Create('hello')];
	aggregateException := EAggregateException.Create(innerExceptions);
	raise aggregateException;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
	try
		raiseAggregate();
	except
		on e: EAggregateException do
			begin
				if (e.Count = 1) then
					raise e.InnerExceptions[0] // <<< that would be too easy
				else
					raise e;
			end
	else
		raise;
	end;
end;

 

How do I do this? I cannot simply use raise e.InnerExceptions[0] because e gets destroyed at the end of the try..except block. This is a problem because e owns its inner exceptions. When gets destroyed, I have basically raised a destroyed exception.

 

In case you're not familiar with the System.Threading.EAggregateException, you check the .NET documentation. Embarcadero documentation does not exist.

Share this post


Link to post

So far, the only solution I have come up with is ripping out the wanted exception with a class helper 🤷‍♂️ and then raise this exception instead.

 

function EAggregateExceptionHelper.Extract(const index: NativeInt): Exception;
var
	newArray: TArray<Exception>;
	arrayIndex: NativeInt;
begin
	newArray := []; Result := nil;
	with self do
		begin
			for arrayIndex := Low(FInnerExceptions) to High(FInnerExceptions) do
				if(arrayIndex = index) then
					Result := FInnerExceptions[arrayIndex]
				else
					newArray := newArray + [FInnerExceptions[arrayIndex]];

			FInnerExceptions := newArray;
		end;
end;

 

Edited by Der schöne Günther

Share this post


Link to post
6 hours ago, Hallvard Vassbotn said:

You can a acquire the exception object to prevent it from being automatically freed.

Yes, but then you are responsible for freeing it yourself. And that doesn't solve the problem of making it release ownership of its inner exceptions.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×