Встретился с ошибкой, когда подключался к сбойному серверу по WebDAV — Far взял и неожиданно закрылся без каких-либо сообщений.
Небольшое расследование показало, что это произошло из-за вызова std::terminate() по причине того, что брошенное исключение осталось необработанным. Это произошло здесь:
Исключение из DoEndTransaction(true) было выкинуто примерно по такой цепочке:
ReadDirectory
DoReadDirectory
exception
перехват catch(Exceptioin &E) в функции TTerminal::ReadDirectory
CommandError
FatalErrorr
throw EConnectionFatal(E, AMsg)
С первого взгляда ничего криминального — по идее брошенное исключение должно быть обработано выше в функции TTerminal::InternalTryOpen, но этого не произошло.
Оказалось, что блок __finally реализован как вызов деструктора, который по умолчанию имеет спецификатор noexcept.
Возможные варианты решения:
Добавить спецификатор noexcept(false) в деструктор
Переписать с использованием SCOPE_EXIT, у которого деструктор уже имеет спецификатор noexcept(false)
Честно говоря, я не знаю сколько ещё блоков __finally содержат в себе функции, которые могут бросать исключения, поэтому проще выглядит вариант 1. Да и вообще логично, что __finally отдаёт исключения наружу для дальнейшей обработки.
Встретился с ошибкой, когда подключался к сбойному серверу по
WebDAV
—Far
взял и неожиданно закрылся без каких-либо сообщений.Небольшое расследование показало, что это произошло из-за вызова
std::terminate()
по причине того, что брошенное исключение осталось необработанным. Это произошло здесь:Исключение из
DoEndTransaction(true)
было выкинуто примерно по такой цепочке:ReadDirectory
DoReadDirectory
catch(Exceptioin &E)
в функцииTTerminal::ReadDirectory
CommandError
FatalErrorr
throw EConnectionFatal(E, AMsg)
С первого взгляда ничего криминального — по идее брошенное исключение должно быть обработано выше в функции
TTerminal::InternalTryOpen
, но этого не произошло.Оказалось, что блок
__finally
реализован как вызов деструктора, который по умолчанию имеет спецификаторnoexcept
.Возможные варианты решения:
noexcept(false)
в деструкторSCOPE_EXIT
, у которого деструктор уже имеет спецификаторnoexcept(false)
Честно говоря, я не знаю сколько ещё блоков
__finally
содержат в себе функции, которые могут бросать исключения, поэтому проще выглядит вариант 1. Да и вообще логично, что__finally
отдаёт исключения наружу для дальнейшей обработки.