Пример:
    
class MyCustomError(Exception):
    def __init__(self, message, code):
        super().__init__(message)
        self.code = code
    def print_error_details(self):
        print(f"Ошибка: {self.args[0]}, Код: {self.code}")
try:
    raise MyCustomError("Что-то пошло не так", 500)
except MyCustomError as e:
    e.print_error_details()
    
  
Для создания собственного исключения в Python и добавления пользовательского метода вывода ошибок, нужно:
Exception или его подкласса.__str__ (или __repr__) для базового класса Exception. Это позволит возвращать строку, описывающую исключение. Внутри этого метода можно вызывать ваш пользовательский метод форматирования.Вот пример:
class CustomError(Exception):
    def __init__(self, message, filename=None, line_number=None):
        super().__init__(message)
        self.filename = filename
        self.line_number = line_number
        self.message = message # Сохраняем сообщение для доступа
    def format_error(self):
        error_string = f"Ошибка: {self.message}"
        if self.filename:
            error_string += f", Файл: {self.filename}"
        if self.line_number:
            error_string += f", Строка: {self.line_number}"
        return error_string
    def __str__(self):
        return self.format_error()
# Пример использования
try:
    raise CustomError("Неверный формат данных", filename="data.txt", line_number=10)
except CustomError as e:
    print(e) # Выведет результат работы __str__
    print(e.format_error()) # Явный вызов пользовательского метода (эквивалентно предыдущему)
Пояснения:
CustomError наследуется от Exception.__init__ принимает сообщение об ошибке и, опционально, имя файла и номер строки.  super().__init__(message) вызывает конструктор родительского класса, передавая ему сообщение.format_error – это пользовательский метод, формирующий строку с информацией об ошибке. Он использует f-строки для удобного форматирования.__str__ переопределен, чтобы возвращать результат format_error().  Когда исключение преобразуется в строку (например, при печати), вызывается именно этот метод.  Метод __repr__ можно переопределить для другого представления объекта, обычно используемого для отладки.Почему это полезно: