Есть ли способ направить swagger codegen для генерации продолжений на основе задач для задач, чтобы перехватить исключение, выданное cpprest? - PullRequest
0 голосов
/ 19 апреля 2019

У меня есть сгенерированный swagger codegen код c ++ с cpprest, который выполняет некоторые вызовы сервера

Проблема, с которой я сталкиваюсь: если запрос cpprest http возвращает какой-либо код ошибки (4xx или 5xx), я получаю следующий сбой при запуске моей программы в CentOS Linux.Если http-запрос cpprest возвращает успех, моя программа не падает.

Callstack сбоя:

0x00007fe97b987207 libc.so.6! Gsignal (+ 0x37) 0x00007fe97b9888f8 libc.so.6! Abort (+ 0x147) 0x0000000007f2478bort_MerServer MySer0x0000000007f24ae1 MyServer! Demangling_terminate_handler () () 0x0000000007f24983 MyServer! Std :: __ terminate (void (*) ()) () 0x0000000007f24a05 MyServer! Std :: terminate (исключение)0x00007fe97c9fdc05 libMyLibrary.so _ZN4pplx7details16_ExceptionHolder21_RethrowUserExceptionEv (+ 0x24) 0x00007fe97c9fea05 libMyLibrary.so _ZN4pplx7details15_Task_impl_base5_WaitEv (+ 0x2e4) 0x00007fe97c9faab6 libMyLibrary.so _ZN5Test18MyManager16CallServerApi1EPKwS2_ibS2_Pwm (+ 0x615)

Пояснение:! В принципе, MyLibrary разделяемый объект имеет функцию CallServerApi1(), который снова вызывает функцию в коде swagger, называемую CallServerApi1 (), что делает запрос cpprest.

Следующий код находится внутри функции CallServerApi1 () класса MyApi в сгенерированном swagger-коде:

 return m_ApiClient->callApi(path, utility::conversions::to_string_t("POST"), queryParams, httpBody, headerParams, formParams, fileParams, requestHttpContentType)
    .then([=](web::http::http_response response)
    {
        // 1xx - informational : OK
        // 2xx - successful       : OK
        // 3xx - redirection   : OK
        // 4xx - client error  : not OK
        // 5xx - client error  : not OK
        if (response.status_code() >= 400)
        {
            //throw my exception with details in case http returned a error response code.
            throw MyException(response.status_code()
                , utility::conversions::to_string_t("error calling CallServerApi1: ") + response.reason_phrase()
                , std::make_shared<std::stringstream>(response.extract_utf8string(true).get()));
        }
        return response.extract_string(); // If successfull return the response data
     });

Мой код в MyLibrary имеет функцию try для отлова MyException, генерируемого кодом swagger.

        try
        {

            auto task = api.CallServerApi1();
            task.wait();
            if (task.is_done())
            {

            }
        }
        catch (const MyException& e)
        {
            string error = e.what();
            int error = e.error_code().value();
        }

Я прочитал здесь: https://docs.microsoft.com/en-us/cpp/parallel/concrt/exception-handling-in-the-concurrency-runtime?view=vs-2019, в котором говорится, что

Когда вы бросаете исключение в теле рабочей функции, которую вы передаете задачеобъект, среда выполнения сохраняет это исключение и направляет его в контекст, который вызывает concurrency :: task :: get или concurrency :: task :: wait.

и

Когда задача выдает исключение, ее продолжения на основе задач планируется запустить.

Насколько я понимаю, поскольку сгенерированный хищником код имеет продолжение на основе задач, а аварийный колл-стэк содержит строку, в которой говорится, что pplx вызывает пользовательское исключение

libMyLibrary.so! _ZN4pplx7details16_ExceptionHolder21_RethrowUserExceptionEv (+ 0x24)

Похоже, что cpprest повторно выдает исключение и не обрабатывается сгенерированным swagger кодом из-за продолжения, основанного на значениях, и, следовательно, происходит сбой, посколькуСтандарт libstdc ++ проинструктирован сделать это для переброшенных исключений.Может кто-нибудь пролить свет на это, может ли это иметь место, и если да, то есть ли способ сообщить swagger code gen, чтобы использовать основанные на задачах продолжения вместо основанных на значениях, чтобы позволить исключению из cpprest проходить и обрабатываться внутризатем () блок?

...