Какой метод Result позволяет выполнить побочный эффект над Err, сохранив исходный результат без преобразования?
Для этого используется Result::inspect_err. Он получает ссылку на ошибку, выполняет переданное действие и возвращает исходный Result без изменения его успешного значения или ошибки.
В обработке ошибок часто требуется наблюдать сбой: записать его в журнал, собрать метрику или отправить диагностическое событие. Преобразовывать ошибку через map_err для такой задачи неудобно, потому что его основное назначение — изменить тип или содержимое ошибки.
inspect_err отделяет наблюдение от преобразования. Благодаря этому диагностический побочный эффект не меняет семантику цепочки обработки.
Если логирование встроить вручную между операциями, код становится многословным и легко случайно изменить ошибку или успешное значение. Если использовать map_err, появляется ложный смысл: будто ошибка действительно преобразуется.
Важно также помнить, что inspect_err не обрабатывает ошибку и не устраняет её. После вызова метода Result по-прежнему содержит тот же Ok или Err, поэтому последующие операции, включая оператор ?, работают как раньше.
inspect_err принимает замыкание, которому передаётся ссылка на значение ошибки. Для Ok замыкание не вызывается, а результат возвращается без изменений. Для Err замыкание выполняется, после чего возвращается исходный Err.
Замыкание получает &E, поэтому оно не забирает ошибку из Result. Это позволяет безопасно осмотреть её, но не заменить, обернуть или вернуть другую ошибку.
Для преобразования ошибки следует использовать map_err, для восстановления после ошибки — or_else, а для окончательного извлечения значения — методы вроде unwrap_or_else. inspect_err предназначен именно для наблюдения и побочных действий.
Побочный эффект должен быть аккуратным: логирование не должно само вызывать panic, блокировать критический путь или раскрывать чувствительные данные. В многопоточном и высоконагруженном коде также нужно учитывать стоимость форматирования и записи журнала.
Сервис читает настройки и возвращает ошибку вызывающему коду. Команде нужно добавить предупреждение в журнал, но сохранить исходный тип std::io::Error, чтобы верхний уровень мог различать отсутствие файла, отказ в доступе и другие причины.
Вариант с map_err формально решает задачу, но требует вернуть ту же ошибку вручную или создать новую обёртку. Это ухудшает выразительность и повышает риск потерять исходный контекст.
Вариант с отдельным match прозрачен, но дублирует передачу Ok и Err и разрастается при длинной цепочке операций. Выбранный вариант — inspect_err: он сохраняет ошибку и добавляет логирование в одной точке.
В результате код верхнего уровня получает первоначальный Result, может применить ? или выполнить собственную классификацию ошибки, а диагностическая запись создаётся только при неуспехе.
inspect_err замыкание для Ok?Нет. Замыкание вызывается только для варианта Err. Для успешного результата метод является прозрачным: он возвращает Ok с тем же значением и не выполняет диагностическое действие.
inspect_err заменить ошибку или изменить её тип?Нет. Замыкание получает ссылку на ошибку и не управляет возвращаемым значением метода. Для преобразования содержимого или типа ошибки используется map_err, а для выбора другой ветви обработки — or_else.
inspect_err на последующий оператор ??Нет, если само замыкание не вызывает аварийное завершение или другой внешний побочный эффект. inspect_err возвращает тот же Result, поэтому оператор ? увидит исходный Ok или Err и применит обычную логику раннего возврата.