Unfortunately, we will have to discard Viorel's suggestion is that TRUNCATE TABLE is DDL. as the explanation. Look at this:
SET XACT_ABORT OFF
BEGIN TRANSACTION
BEGIN TRY
PRINT 'Prints'
ALTER TABLE nosuchtable ALTER COLUMN col a
END TRY
BEGIN CATCH
SELECT xact_state() AS xact_state, error_message() AS errmsg
END CATCH
PRINT 'Does not print'
go
SELECT @@trancount
IF @@trancount > 0 ROLLBACK TRANSACTION
The output is:
Prints
Msg 4902, Level 16, State 1, Line 128
Cannot find the object "nosuchtable" because it does not exist or you do not have permissions.
-----------
1
Which is the same output as we get when have DELETE nosuchtable
.
So I will go back to my original answer: because error handling in SQL Server is a big mess.