1. C# / Говнокод #26531

    0

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    try
           {
                await storageClient.DownloadObjectAsync(Bucket, fileName, stream).ConfigureAwait(false);
           }
        catch(Exception ex)
           {
                throw new FileStorageException($"File '{fileName}' not found in a bucket '{Bucket}'", ex) { StatusCode = StatusCodes.Status404NotFound };
           }

    Сеньйор дот нет девелопер

    Запостил: horil97821, 26 Марта 2020

    Комментарии (70) RSS

    • Что не так?
      Ответить
      • видимо await ... .ConfigureAwait(false). но зачем всё остальное - тоже не понял
        Ответить
        • Переведи на пхп, ничерта не понятно
          Ответить
          • <?php
            $socket = socket_create_listen(1223);
            socket_set_nonblock($socket);
            
            socket_accept($socket);
            ?>
            Ответить
            • Получилось намного короче! Именно поэтому я за «PHP».
              Ответить
            • А если серьёзно, то «bucket» — это слишком специфическое слово. Это из API какого-нибудь «AWS»?
              Ответить
              • Когда апостол Пётр даст тебе серебряную указку и попросит прочесть тору, увидев алеф говори "ба" - и попадешь в рай.
                Евреев туда не пустят.
                Ответить
            • Зачем закрыл тег ? И что это за функции ? Аналоги strip_tags ?
              Ответить
      • ну и вообще стрелять "нихуя не найдено" на любое исключение - тоже говно
        Ответить
    • то есть ничего не смущает тот факт, что в что в эксепшене создается еще один эксепшн?
      Ответить
      • Это-то как раз норма. ConfigureAwait() может бросать какое-нибудь HttpException, а этот код просто переводит его в более удобный вид: во-первых, с понятным сообщением об ошибке, а во-вторых — вызывающему этот код не нужно будет импортировать HTTP-либу и разбираться в её деталях, вместо этого вызывающий просто ловит FileStorageException и течёт.

        А вот ловля «Exception ex» — это говно, да.
        Ответить
        • иными словами отдебажить потом будет ооочень нелегко.... и по хорошему нужно не ошибку писать а писать в лог...
          Ответить
          • Если заменить «catch (Exception ex)» на правильное «catch(HttpException ex)» (ну и обработать другие возможные вореанты) — то почему это должно быть сложно дебажить?
            Писать в лог нужно далеко не всегда, важен коньтекст. Если этот код — из либы для работы с какой-то сетевой ФС, то выбрасывания подробного, семантически верного, исключения вполне достаточно, либе совершенно не обязательно срать в лог, это оверинжиниринг. В лог писать должен тот код, который этот самый FileStorageException поймает.
            Ответить
            • ога например креды сдохли и как ты поймешь это?) Выведешь эксепшн в который не входит это ошибка - ну ок)
              Ответить
              • Очень просто:
                catch(HttpException ex) when (ex.StatusCode == 403)
                {
                    throw new FileStorageException($"Couldn't load the file {Filename}: access denied", ex) { StatusCode = StatusCodes.Status403AccesDenied };
                }
                Ответить
                • статус кода нет, в том то и дело... так бы на изи
                  Ответить
                  • Так значит надо добавить и всё. Проблем именно с тем, что
                    >>> в эксепшене создается еще один эксепшн
                    нет.
                    Ответить
                • [сode]
                  catch(HttpException ex) when (ex.StatusCode == 403)
                  [/сode]
                  А шо, так можно?
                  Ответить
                  • Оказывается, можно.
                    https://ideone.com/zXstg3
                    Ответить
                    • многомерный трай кетч это - говнокод
                      Ответить
                      • засунул тебя в тессеракт, проверь
                        Ответить
                        • говорила мне мать, сынок просто женись и бухай)
                          Ответить
                      • Многомерный — это какой?
                        Ответить
                        • кетч кетч кетч 3 раза это неочень конструкция даже при вене
                          Ответить
                          • Вовсе нет, это совершенно нормальная конструкция. В моём — синтетическом — примере, её ещё можно заменить на switch-case, а как ты предлагаешь обрабатывать метод, который может выкинуть, например, ArgumentError, ArithmeticException или InvalidCastException?
                            Ответить
                            • это что должно произойти в жизни чтобы такие ексепшены вывалились?
                              Ответить
                              • Что угодно. Ладно, другой пример: есть либа, в ней есть метод DownloadFile(filename, bucket, auth), этот метод может выкинуть FileNotFoundError, BucketNotFoundError, WrongAuthError и ConnectionError. Опиши, как ты будешь обрабатывать эти ошибки, не используя последовательные catch-блоки.
                                Ответить
                                • мне нужна ошибка общего типо в логи, и она уже даст ответ на мои вопросы, а не конкретная в окно браузера, лол
                                  Ответить
                                  • Чего? Ещё раз, как ты предлагаешь ловить исключения разных типов без последовательных catch-блоков?
                                    Ответить
                                    • в один трай кетч и все
                                      Ответить
                                      • И как отличать потом что случилось?
                                        var url = GetUrl("введите урл вашей странички вкантаки");
                                        try 
                                        {
                                          PoslatNahui(url);
                                        } catch (UrlNotFound ex) {
                                          Console.Write("Извините, вы напиздели, у вас нет вкантакте");
                                        } catch (NetworkError ex) {
                                          Console.Write("Извините, у нас отвалился интернет");
                                        }
                                        Ответить
                                        • Упс. Произошла какая-то ошибка.

                                          Сейчас так модно делать.
                                          Ответить
                                          • Обратитесь к системному администратору.
                                            Ответить
                                          • На самом деле проблема в том, что исключения (как и HRESULT, и что угодно) бывает двух видов:

                                            * Вполне ожидаемые проблемы, являющиеся частью бизнес-логики. Например ввод неверного имени. Недоступность сети может быть такой проблемой, а может и не быть: зависит от того, что за приложение. В Java это Checkeed Exceptions. В нормальных языках это монада типа Result.

                                            * Пиздецы. NPE/NRE. OutOfMemory, ClassNotFound (если конечно это не введенный пользователем класс). Такие ошибки не надо ловить никогда (кроме как если ты пишешь сервер приложений). Их надо рассматривать как DivisionByZero, и схлопывать приложение.

                                            Надо ли показывать пиздецы пользователю?
                                            В веб-приложении однозначно НЕ надо (если ты не пыхапист), но их надо писать в лог.
                                            В десктопном надо (иначе как он поймет, что случилось?), но можно и их тоже записать в лог, чтобы их потом показали разрабам.

                                            В идеальном мире исключения используются только для пиздецов, а для бизнес-логики есть другие инструменты. К сожалению в жабе, например, это единственный способ внятно вернуть ошибку так, чтобы клиент класса её проверил.
                                            Ответить
                                          • Мелким шрифтом, и вокруг - реклама. Привет амазон!
                                            Ответить
                            • ArgumentError, ArithmeticException или InvalidCastException ловить не надо ни в коем случае, если ты не пишешь инфраструктурный код
                              Ответить
        • Кстати, про ConfigureAwait(false). В «ASP.NET Core» нет никакого «SynchronizationContext» (в отличие от старого ASP.NET), поэтому ConfigureAwait(false) больше не нужен. Можно блокировать асинхронный код и не опасаться дедлоков. Именно поэтому я за «ASP.NET Core».
          Ответить
    • А почему все три параметра DownloadObjectAsync в разных нотациях?
      ex тоже в camel case
      а StatusCode в pascal case.
      Это у шарперов норм?
      Ответить
      • Нет конечно.

        Переменные пишутся с маленькой буквы. Филды классов, имена функций и классов -- с большой.

        var petuh = 32;
        Console.Write(new Petuh(petuh).Petuh);
        Ответить
        • Какая-то говноконвенция, to be honest with you.
          Впрочем, это же Visual BRACIS...
          Ответить
        • > филды с большой

          Зачем? Зачем? Чем они от переменных отличаются?
          Ответить
          • Причем он еще умудрился в штаны дриснуть обозвав метод полем.
            Ответить
            • Скоро вы все будете лежать на поле, точнее, в поле, и разница между методами и свойствами будет для Вас уже не столь очевидна. Вороны будут клевать ваши высохшие глаза.
              Ответить
          • тем, что они методы.

            На самом деле я наврал
            С большой буквы пишутся проперти
            Проперти это по сути аксессоры и мутаторы
            Ответить
          • Паблик филды пишутся с прописной буквы (но вообще, лучше вместо них использовать проперти).
            Для приватных строгого соглашения нет, и вот их как правило пишут со строчной, как обычную переменную; некоторые ещё андерскор впереди добавляют.
            https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/capitalization-conventions
            Ответить
            • я имел ввиду пропертю конечно.
              Публичные филды не нужны, когда есть сахар set;get;. Лучше сразу делать проперти, чтобы потом не сломалось abi, когшда решиш инкапсулировать
              Ответить
    • Охуительная практика использовать эксепшены как часть логики программы
      Неужели у storageClient нет метода "проверить наличие файла"?
      Ответить
      • > Неужели у storageClient нет метода "проверить наличие файла"?
        Судя по https://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.Storage.V1/api/Google.Cloud.Storage.V1.StorageClient.ht ml — именно такого нет, разве что GetObject().

        Впрочем, он и не нужен: в распределённых приложениях паттерн «проверить наличие, потом использовать» — априори говно.
        Ответить
        • Это где угодно говно кроме работы с памятью: Даже на твоем локальном диске файл может исчезнуть. CAS в обычные ФС еще не завезли вроде
          Ответить
          • строго говоря, в редких ситуациях проще проверить наличие/отсутствие, прежде чем начинать операцию, если первое в разы дешевле
            Ответить
        • >Впрочем, он и не нужен: в распределённых приложениях паттерн «проверить наличие, потом использовать» — априори говно.
          Если эта хуйня упакована в storageClient, можно было бы создавать какой-нибудь StorageClientInstance, который бы под капотом делал один запрос, но поддерживал бы оба метода, храня в себе состояние этого запроса. Разве получилось бы хуево?
          Ответить
          • Да, хуёво. Потому что тогда метод «проверить наличие файла» должен скачивать весь файл, чтобы обеспечить работоспособность подхода «проверить наличие, потом использовать». Правда, в этом случае мы огребаем дичайшие проблемы синхронизации, когда в нашем локальном состоянии файл есть, а на сервере его уже нет, и даже какой-нибудь getFilesCount() возвращает 0.
            Ответить
            • Не нужно нажимать на кнопочки и пачкать экран. Лучше выйди на улицу и сделай глубокий вдох.
              Ответить
      • Мне больше всего нравится, что любой эксепшен интерпретируется как «файл не найден». А если просто интернет отвалился или Роскомнадзор?
        Ответить
        • или NRE
          Ответить
        • В «Windows» команда «ipconfig /renew» иногда выдаёт ответ: «Файл не найден». Причём она не говорит, какой именно. Хотя на самом деле не найден не файл, а маршрут.
          Ответить
        • Всё верно: тогда вообще никаких файлов не будет.
          Ответить
        • «файл не найден» это ошибка №2, победа на конкурсе мудаков
          Ответить
          • подумал что речь идет про тотал коммандер.
            Ответить
            • подумал что ты ответил уёбку
              не ошибся
              Ответить
            • Ошибка №1 - скачивать тотал коммандер написанный на Bormand Delhi, а ошибка №2 - разрешать элевацию инсталлятора тотал коммандер написанного на Bormand Delhi. А FAR - это ERROR_SUCCESS.
              Ответить

    Добавить комментарий