Now I see the bug! I did not look carefully enough last night. This is plain wrong:
IF @@tranCount = 1
ROLLBACK TRANSACTION
That should be
IF @@tranCount > 0
ROLLBACK TRANSACTION
Look at the error message you got:
Transaction count after EXECUTE indicates a mismatching number of BEGIN and COMMIT statements. Previous count = 1, current count = 2.
At the time of the error, the procedure was called inside a transaction, so @@trancount was 1. The procedure itself started a nested transaction which bumped @@trancount to 2. But the CATCH block did not roll back the transaction in this case. You should be able to reproduce this situation this way:
BEGIN TRANSACTION
EXEC dbo.AddEvent <with a parameter that leads to an error>
go
SELECT @@trancount
IF @@trancount > 0 ROLLBACK TRANSACTION
A second flaw is that the procedure does not re-raise the error. Yes, I see that you return an error code, and I guess your client code looks at the return value. But if you nest stored procedures, looking at return codes is tedious. It's better to re-raise the error, so that outer CATCH handlers - be that in calling procedures or client code are activated.
I have a series of articles about error and transaction handling on my web site. Part One gives you a head start by simply describing good ways to implement TRY-CATCH. Part Two and Part Three are much longer and discusses a lot of nasty details with error handling in SQL Server. Start here: https://www.sommarskog.se/error_handling/Part1.html.