Несколько дней назад мне на глаза попалась ссылка на Gemini-эмулятор текстовых квестов из игры "Космические Рейнджеры":
И довелось мне зайти на него с использованием yah2g. При клике на любом квесте возникала ошибка с не очень информативным описанием:
'latin-1' codec can't encode characters in position 71-79: ordinal not in range(256).
Предыдущая запись дневника разработки yah2g
Понятно, что этот Gemini-эмулятор сохраняет состояние на основе клиентского сертификата и yah2g работать с ним точно не будет. Но ошибка-то выпадает какая-то другая, да к тому же совсем не информативная. Распечатав стек вызовов в момент возникновения исключения я докапал до такого фрагмента:
self._headers_buffer.append(("%s %d %s\r\n" % (self.protocol_version, code, message)).encode( 'latin-1', 'strict'))
https://github.com/python/cpython/blob/3.11/Lib/http/server.py#L516
То есть сообщение об ошибке, ожидаемо, упаковывалось в заголовок HTTP ответа. И там (в заголовке) ожидаются только latin-1 символы. А Gemini-эмулятор, в нашем случае, в сообщении об ошибке возвращал описание на английском и на русском языках. Русские символы не входят в latin-1, из-за чего и возникала ошибка.
Благо у BaseHTTPRequestHandler.send_error помимо аргумента message (который, как выяснилось, помещается и заголовок) присутствует аргумент explain, который просто форматируется в тело ответа, а значит будет отрендерен пользователю браузера. Суть исправления в том, что бы передавать возвращённую Gemini сервером строку в аргумент explain. После этого стала отображаться информативная страница об ошибке:
Message: Unsupported answer: 60.
Error code explanation: HTTPStatus.INTERNAL_SERVER_ERROR - Ranger certificate required / Требуется сертификат рейнджера.
Исправление внесено в исходный код и зафиксировано в репозитории тэгом v0.5.
Комментарии через ActivityPub (Fediverse) можно оставить здесь: