Как правильно написать свой обработчик ошибок php?
Перед тем как писать обработчик, надо сначала понять, а зачем он нужен. 
Потому что вот эта вот функция - она совершенно бессмысленная. 
Вся "обработка", которой она занимается - это добавляет бессмысленные фразы типа "Error_message" к тому что РНР выведет и так. 

Обработчик ошибок не должен заниматься удалением файлов. Обработчик вступает в дело, когда ничего исправить уже нельзя, и всё что остаётся - это показать пользователю страницу с извинениями и корректным НТТР кодом. Пример можно взять здесь: https://phpdelusions.net/articles/error_reporting

А вот обрабатывать ошибки надо с помощью оператора  try catch
Если надо откатить транзакцию, то всю её целиком надо поместить внутрь  try catch, в котором ловить ВСЕ ошибки, то есть \Throwable и после этого скорее всего добавить throw с тем же исключением, поскольку вряд ли при ошибке БД имеет смысл продолжать работу скрипта. Но зависит от обстоятельств.

Если надо удалить файлы, то опять же, заключить в try catch загрузку файлов, то тут просто заключить в try catch, всё почистить и написать какое-нибудь сообщение пользователю.
Если в скрипте произошла ошибка, то как мне откатить транзакциюстарайся чтобы все, что касается работы с каким то объектом, у которого состояние требует реакции (закрытие файла, транзакции бд и т.п.) то настоятельно рекомендуется описывать всю логику примерно на одном уровне/в одном месте

Не рекомендуется пытаться делать где то один мега крутой метод который все закроет, финализирует и освободит, как только произойдет фатальная ошибка (а именно так будет работать php с базами данных и файлами). Например это можно сделать через описание деструкторов классов-пустышек с одним объектом в мемберах, определяемых для каждого отдельного случая, в этом случае перед завершением работы скрипта будут вызваны все десктрукторы (порядок вызова - с осторожностью, сложен для прогнозирования).

Язык программирования php рекомендует и предлагает для этого конструкцию try catch finaly, там где может произойти ошибка, в catch прописывай логику завершения именно данной секции (откатить транзакцию) и вызывай следующий throw по цепочке, в finaly же прописывай то что нужно исполнить в любом случае.

Да это потребует вдумчиво везде где только можно следить за ошибками, но такова селяви, либо ты надеешься на авось и автоматизацию либо следишь за всем сам.