Возврат ошибок из недр вложенных вызовов
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 04.11.20 21:09
Оценка:
Типичная ситуация: функция верхнего уровня вызывает функцию более низкого уровня, та — следующую и т.п., и где-то на N-м уровне очередной вызов возвращает ошибку. Если это что-то уникальное, то можно вернуть наверх (хоть через обычные return, хоть через исключения) уникальный код и/или описание. Но если ошибка общего характера (нехватка ресурсов, отказ в доступе, разрыв соединения и т.п.), то неплохо бы вернуть наверх более подробную информацию, которую можно показать пользователю, чтобы он имел более-менее адекватное представление о проблеме.

Например, в винде издавна принято возвращать отовсюду HRESULT. В результате, например, Windows Update при любой проблеме тупо выдает "failed" вместе с HRESULT, и даже по логам не сразу определишь, что и где обломалось. А программы на фреймворках типа .NET, наоборот, могут столь же тупо вывалить пользователю раскрутку стека, из которой он тоже мало что поймет, и которую таки лучше писать в лог. Хочется выдавать нечто промежуточное — не абстрактный "access denied", но и не историю вложенных вызовов в чистом виде.

Возникает соблазн завести какой-нибудь универсальный класс Result, и в процессе возврата изнутри наружу добавлять в объект уточнения, если необходимо. Но если возвращать его обычным образом, через return, то RVO/NRVO в отладочном режиме [практически] не используется, возвращаемые объекты (где будут минимум сотни байт) будут многократно копироваться, а функции нижнего уровня могут вызываться и сотни-тысячи раз в секунду. По той же причине не всегда годятся исключения — функции нижнего уровня не всегда возвращают ошибки, фатальные для верхних уровней.

Другой вариант — использовать TLS, как в винде для GetLastError. А как с этим в Linix/MacOS/Android/iOS?

Вообще, какие способы возврата уточненных результатов из многократно вложенных вызовов ныне считаются кошерными?
результат ошибка код rvo nrvo оптимизация getlasterror вложенный
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.