We currently use this template for any queries that we execute (you could leave out the Transaction stuff, if you don't need it in e.g. a DDL statement):
BEGIN TRANSACTION
BEGIN TRY
// do your SQL statements here
COMMIT TRANSACTION
END TRY
BEGIN CATCH
SELECT
ERROR_NUMBER() AS ErrorNumber,
ERROR_SEVERITY() AS ErrorSeverity,
ERROR_STATE() AS ErrorState,
ERROR_PROCEDURE() AS ErrorProcedure,
ERROR_LINE() AS ErrorLine,
ERROR_MESSAGE() AS ErrorMessage
ROLLBACK TRANSACTION
END CATCH
Of course, you could easily insert the caught exception into your error log table.
It works really well for us. You could probably even automate some of the conversion from your old stored procs to a new format using Code Generation (e.g. CodeSmith) or some custom C# code.