Stupid Mistakes: Tridion Event System and Async Subscriptions

It’s easy to make one of those simple and stupid mistakes when developing with Tridion.  You know, one of those mistakes that make you lose an hour or more to debugging.  One of those mistakes that, after realizing what you did wrong, you are extremely happy you found the issue, but at the same time still just a bit embarrassed that you missed it in the first place.  I thought I’d share one that I made over the weekend in hopes that perhaps if someone else accidently went down the wrong path they’d quickly be able to correct themselves.

Over the weekend I was working on some Event System code that worked with Multimedia Components.  I’ll spare most of the details, but the code had to do two main things: 1.) Get the binary data out of the Multimedia Component and 2.) Set a Metadata Field to a value if the field was empty.  Pretty easy right?  We’ve all done these things before and this kind of functionality should be smooth sailing.  Until its not…

Coded. Deployed. Created a new Multimedia Component.  Save and Closed.  And… wth? The Event Log showed the following error.

A database error occurred while executing Stored Procedure "EDA_ITEMS.GETBINARYCONTENT".
ORA-01403: no data found
ORA-06512: at "TRIDION_CM.EDA_ITEMS", line 4100
ORA-06512: at line 1

Looks like my code didn’t like my call to the GetByteArray() method… weird. This portion of the Event System was using the Processed event phase. Interestingly, switching it to Initiated made the error go away. Shouldn’t be a solution, but hey, it was working now. I’ll move on and figure out the root issue later.

Next I added code to set the Metadata Field when it was null. Coded. Deployed. Saved and Closed the modified MM component. And… wth again? The Event Log now showed the following error.

The item tcm:123-4567-16-v0 does not exist.

Another piece of code I’ve done countless times… why is it failing now?  Tridion, why have you forsaken me!?!

The Issue

After much debugging and even coming up with a workaround to get my code working, I looked up at the piece that was subscribing my event and immediately face palmed.

EventSystem.SubscribeAsync<Component, SaveEventArgs>(OnComponentSaveInitiated, EventPhases.Initiated);

Can you see the issue above? Yep, I had subscribed my event asynchronously, and those weird issues I was seeing was the price I paid for doing it incorrectly.  For those of you who are not familiar with the Tridion Event System, you should only subscribe events asynchronously via the SubscribeAsync method with a TransactionCommitted phase.

What had happened was, when I started on this Event Handler, I had a different set of requirements. I was originally going to use a TrasnactionCommitted phase and a Check In event, and started coding it, but switched to the Initiated phase with a Save event once I got the updated requirements. Unfortunately, I forgot to change the subscription method to not subscribe asynchronously.

EventSystem.Subscribe<Component, SaveEventArgs>(OnComponentSaveInitiated, EventPhases.Initiated);

Ah, all better now…

Another Clue…

Another clue that I had used the wrong subscription method should have been the errors themselves. Normally when an Exception is thrown in the Initiated or Processed phase, that error prevents the save, and the error message is displayed to the user. With my code, the component was saving just fine, and the error message was only getting logged and not communicated to the user.