languagetool show cURL errors with the interaction handler

Only shows the error once for a given checkerURL.

Change-Id: I1873dc09584df33162c93d9d133b12eb8dfede04
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169518
Reviewed-by: Michael Stahl <michael.stahl@allotropia.de>
Tested-by: Jenkins
Reviewed-by: Sarper Akdemir <sarper.akdemir@allotropia.de>
This commit is contained in:
Sarper Akdemir 2024-06-21 12:39:50 +02:00
parent 2e87c64424
commit a7d1a6f313
3 changed files with 68 additions and 14 deletions

View File

@ -23,6 +23,7 @@ $(eval $(call gb_Library_use_libraries,LanguageTool,\
comphelper \ comphelper \
cppu \ cppu \
cppuhelper \ cppuhelper \
fwk \
i18nlangtag \ i18nlangtag \
svt \ svt \
lng \ lng \

View File

@ -47,8 +47,13 @@
#include <sal/log.hxx> #include <sal/log.hxx>
#include <tools/color.hxx> #include <tools/color.hxx>
#include <tools/long.hxx> #include <tools/long.hxx>
#include <framework/interaction.hxx>
#include <com/sun/star/task/InteractionClassification.hpp>
#include <com/sun/star/task/InteractionHandler.hpp>
#include <com/sun/star/text/TextMarkupType.hpp> #include <com/sun/star/text/TextMarkupType.hpp>
#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
#include <com/sun/star/uno/Any.hxx> #include <com/sun/star/uno/Any.hxx>
#include <comphelper/interaction.hxx>
#include <comphelper/propertyvalue.hxx> #include <comphelper/propertyvalue.hxx>
#include <unotools/lingucfg.hxx> #include <unotools/lingucfg.hxx>
#include <osl/mutex.hxx> #include <osl/mutex.hxx>
@ -121,7 +126,7 @@ enum class HTTP_METHOD
std::string makeHttpRequest_impl(std::u16string_view aURL, HTTP_METHOD method, std::string makeHttpRequest_impl(std::u16string_view aURL, HTTP_METHOD method,
const OString& aPostData, curl_slist* pHttpHeader, const OString& aPostData, curl_slist* pHttpHeader,
tools::Long& nStatusCode) tools::Long& nStatusCode, CURLcode& eCURLCode)
{ {
struct curl_cleanup_t struct curl_cleanup_t
{ {
@ -160,11 +165,12 @@ std::string makeHttpRequest_impl(std::u16string_view aURL, HTTP_METHOD method,
(void)curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS, aPostData.getStr()); (void)curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS, aPostData.getStr());
} }
CURLcode cc = curl_easy_perform(curl.get()); eCURLCode = curl_easy_perform(curl.get());
if (cc != CURLE_OK) if (eCURLCode != CURLE_OK)
{ {
SAL_WARN("languagetool", SAL_WARN("languagetool",
"CURL request returned with error: " << static_cast<sal_Int32>(cc)); "CURL request returned with error: " << static_cast<sal_Int32>(eCURLCode) << " "
<< curl_easy_strerror(eCURLCode));
} }
curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &nStatusCode); curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &nStatusCode);
@ -172,7 +178,7 @@ std::string makeHttpRequest_impl(std::u16string_view aURL, HTTP_METHOD method,
} }
std::string makeDudenHttpRequest(std::u16string_view aURL, const OString& aPostData, std::string makeDudenHttpRequest(std::u16string_view aURL, const OString& aPostData,
tools::Long& nStatusCode) tools::Long& nStatusCode, CURLcode& eCURLCode)
{ {
struct curl_slist* pList = nullptr; struct curl_slist* pList = nullptr;
OString sAccessToken OString sAccessToken
@ -186,11 +192,12 @@ std::string makeDudenHttpRequest(std::u16string_view aURL, const OString& aPostD
pList = curl_slist_append(pList, sAccessToken.getStr()); pList = curl_slist_append(pList, sAccessToken.getStr());
} }
return makeHttpRequest_impl(aURL, HTTP_METHOD::HTTP_POST, aPostData, pList, nStatusCode); return makeHttpRequest_impl(aURL, HTTP_METHOD::HTTP_POST, aPostData, pList, nStatusCode,
eCURLCode);
} }
std::string makeHttpRequest(std::u16string_view aURL, HTTP_METHOD method, const OString& aPostData, std::string makeHttpRequest(std::u16string_view aURL, HTTP_METHOD method, const OString& aPostData,
tools::Long& nStatusCode) tools::Long& nStatusCode, CURLcode& eCURLCode)
{ {
OString realPostData(aPostData); OString realPostData(aPostData);
if (method == HTTP_METHOD::HTTP_POST) if (method == HTTP_METHOD::HTTP_POST)
@ -202,7 +209,7 @@ std::string makeHttpRequest(std::u16string_view aURL, HTTP_METHOD method, const
realPostData += "&username=" + encodeTextForLT(username) + "&apiKey=" + apiKey; realPostData += "&username=" + encodeTextForLT(username) + "&apiKey=" + apiKey;
} }
return makeHttpRequest_impl(aURL, method, realPostData, nullptr, nStatusCode); return makeHttpRequest_impl(aURL, method, realPostData, nullptr, nStatusCode, eCURLCode);
} }
template <typename Func> template <typename Func>
@ -301,10 +308,41 @@ OUString getCheckerURL()
return *oURL + "/check"; return *oURL + "/check";
return {}; return {};
} }
void lclShowCURLErrorInteraction(const css::uno::Reference<css::uno::XComponentContext>& xContext,
CURLcode eCURLCode, const OUString& rServer)
{
if (!xContext.is())
return;
css::uno::Reference<task::XInteractionHandler2> xInteractionHandler
= task::InteractionHandler::createWithParent(xContext, nullptr);
if (!xInteractionHandler.is())
return;
css::uno::Any aInteraction;
rtl::Reference<comphelper::OInteractionApprove> pApprove
= new comphelper::OInteractionApprove();
css::uno::Sequence<css::uno::Reference<css::task::XInteractionContinuation>> aContinuations{
pApprove
};
ucb::InteractiveNetworkConnectException aException(
{ "(" + OUString::number(eCURLCode) + ") "
+ OStringToOUString(curl_easy_strerror(eCURLCode), RTL_TEXTENCODING_UTF8) },
{}, task::InteractionClassification_ERROR, rServer);
aInteraction <<= aException;
xInteractionHandler->handle(
framework::InteractionRequest::CreateRequest(aInteraction, aContinuations));
}
} }
LanguageToolGrammarChecker::LanguageToolGrammarChecker() LanguageToolGrammarChecker::LanguageToolGrammarChecker(
const css::uno::Reference<css::uno::XComponentContext>& xContext)
: mCachedResults(10) : mCachedResults(10)
, mxContext(xContext)
{ {
} }
@ -452,10 +490,22 @@ ProofreadingResult SAL_CALL LanguageToolGrammarChecker::doProofreading(
tools::Long http_code = 0; tools::Long http_code = 0;
std::string response_body; std::string response_body;
CURLcode eCURLCode = CURLE_OK;
if (bDudenProtocol) if (bDudenProtocol)
response_body = makeDudenHttpRequest(checkerURL, postData, http_code); response_body = makeDudenHttpRequest(checkerURL, postData, http_code, eCURLCode);
else else
response_body = makeHttpRequest(checkerURL, HTTP_METHOD::HTTP_POST, postData, http_code); response_body
= makeHttpRequest(checkerURL, HTTP_METHOD::HTTP_POST, postData, http_code, eCURLCode);
if (eCURLCode != CURLE_OK)
{
// show the cURL error only once for a given checkerURL
if (maLastErrorCheckerURL != checkerURL)
{
maLastErrorCheckerURL = checkerURL;
lclShowCURLErrorInteraction(mxContext, eCURLCode, checkerURL);
}
}
if (http_code != 200) if (http_code != 200)
{ {
@ -512,9 +562,9 @@ void SAL_CALL LanguageToolGrammarChecker::initialize(const uno::Sequence<uno::An
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
lingucomponent_LanguageToolGrammarChecker_get_implementation( lingucomponent_LanguageToolGrammarChecker_get_implementation(
css::uno::XComponentContext*, css::uno::Sequence<css::uno::Any> const&) css::uno::XComponentContext* pContext, css::uno::Sequence<css::uno::Any> const&)
{ {
return cppu::acquire(new LanguageToolGrammarChecker()); return cppu::acquire(new LanguageToolGrammarChecker(pContext));
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */

View File

@ -25,6 +25,7 @@
#include <com/sun/star/linguistic2/ProofreadingResult.hpp> #include <com/sun/star/linguistic2/ProofreadingResult.hpp>
#include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyValues.hpp> #include <com/sun/star/beans/PropertyValues.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <linguistic/misc.hxx> #include <linguistic/misc.hxx>
#include <string_view> #include <string_view>
#include <o3tl/lru_map.hxx> #include <o3tl/lru_map.hxx>
@ -37,11 +38,13 @@ class LanguageToolGrammarChecker
css::uno::Sequence<css::lang::Locale> m_aSuppLocales; css::uno::Sequence<css::lang::Locale> m_aSuppLocales;
o3tl::lru_map<OString, css::uno::Sequence<css::linguistic2::SingleProofreadingError>> o3tl::lru_map<OString, css::uno::Sequence<css::linguistic2::SingleProofreadingError>>
mCachedResults; mCachedResults;
css::uno::Reference<css::uno::XComponentContext> mxContext;
OUString maLastErrorCheckerURL;
LanguageToolGrammarChecker(const LanguageToolGrammarChecker&) = delete; LanguageToolGrammarChecker(const LanguageToolGrammarChecker&) = delete;
LanguageToolGrammarChecker& operator=(const LanguageToolGrammarChecker&) = delete; LanguageToolGrammarChecker& operator=(const LanguageToolGrammarChecker&) = delete;
public: public:
LanguageToolGrammarChecker(); LanguageToolGrammarChecker(const css::uno::Reference<css::uno::XComponentContext>& xContext);
virtual ~LanguageToolGrammarChecker() override; virtual ~LanguageToolGrammarChecker() override;
// XSupportedLocales // XSupportedLocales