From d9362e6687d1b2e3f834b9b8c1a62dd2cfeb2f00 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Thu, 18 Sep 2025 09:28:39 +1000 Subject: [PATCH] [api] Introduce flag to disable error message logging for network requests Fixes #53721 --- python/PyQt6/core/auto_additions/qgis.py | 14 +++++++ .../network/qgsblockingnetworkrequest.sip.in | 13 ++++++- .../network/qgsnetworkaccessmanager.sip.in | 8 +++- python/PyQt6/core/auto_generated/qgis.sip.in | 10 +++++ python/core/auto_additions/qgis.py | 13 +++++++ .../network/qgsblockingnetworkrequest.sip.in | 13 ++++++- .../network/qgsnetworkaccessmanager.sip.in | 8 +++- python/core/auto_generated/qgis.sip.in | 10 +++++ .../network/qgsblockingnetworkrequest.cpp | 38 +++++++++++++++---- src/core/network/qgsblockingnetworkrequest.h | 17 ++++++++- src/core/network/qgsnetworkaccessmanager.cpp | 8 ++-- src/core/network/qgsnetworkaccessmanager.h | 8 +++- src/core/qgis.h | 20 ++++++++++ 13 files changed, 156 insertions(+), 24 deletions(-) diff --git a/python/PyQt6/core/auto_additions/qgis.py b/python/PyQt6/core/auto_additions/qgis.py index 2dfa59d555f..c61b219e376 100644 --- a/python/PyQt6/core/auto_additions/qgis.py +++ b/python/PyQt6/core/auto_additions/qgis.py @@ -75,6 +75,20 @@ Qgis.Critical = Qgis.MessageLevel.Critical Qgis.Success = Qgis.MessageLevel.Success Qgis.NoLevel = Qgis.MessageLevel.NoLevel Qgis.MessageLevel.baseClass = Qgis +# monkey patching scoped based enum +Qgis.NetworkRequestFlag.DisableMessageLogging.__doc__ = "If present, indicates that no message logging should be performed when network errors are encountered" +Qgis.NetworkRequestFlag.__doc__ = """Flags controlling behavior of network requests. + +.. versionadded:: 4.0 + +* ``DisableMessageLogging``: If present, indicates that no message logging should be performed when network errors are encountered + +""" +# -- +Qgis.NetworkRequestFlag.baseClass = Qgis +Qgis.NetworkRequestFlags = lambda flags=0: Qgis.NetworkRequestFlag(flags) +Qgis.NetworkRequestFlags.baseClass = Qgis +NetworkRequestFlags = Qgis # dirty hack since SIP seems to introduce the flags in module QgsMapLayer.LayerType = Qgis.LayerType # monkey patching scoped based enum QgsMapLayer.VectorLayer = Qgis.LayerType.Vector diff --git a/python/PyQt6/core/auto_generated/network/qgsblockingnetworkrequest.sip.in b/python/PyQt6/core/auto_generated/network/qgsblockingnetworkrequest.sip.in index 085b71a262e..b89a00710fc 100644 --- a/python/PyQt6/core/auto_generated/network/qgsblockingnetworkrequest.sip.in +++ b/python/PyQt6/core/auto_generated/network/qgsblockingnetworkrequest.sip.in @@ -50,13 +50,22 @@ copy and pass between threads without issue. typedef QFlags RequestFlags; - explicit QgsBlockingNetworkRequest(); + explicit QgsBlockingNetworkRequest( Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() ); %Docstring -Constructor for QgsBlockingNetworkRequest +Constructor for QgsBlockingNetworkRequest. + +The ``flags`` argument was added in QGIS 4.0 %End ~QgsBlockingNetworkRequest(); + Qgis::NetworkRequestFlags flags() const; +%Docstring +Returns the network request flags. + +.. versionadded:: 4.0 +%End + ErrorCode get( QNetworkRequest &request, bool forceRefresh = false, QgsFeedback *feedback = 0, RequestFlags requestFlags = QgsBlockingNetworkRequest::RequestFlags() ); %Docstring Performs a "get" operation on the specified ``request``. diff --git a/python/PyQt6/core/auto_generated/network/qgsnetworkaccessmanager.sip.in b/python/PyQt6/core/auto_generated/network/qgsnetworkaccessmanager.sip.in index 26fce945fe7..6fedb5bfa48 100644 --- a/python/PyQt6/core/auto_generated/network/qgsnetworkaccessmanager.sip.in +++ b/python/PyQt6/core/auto_generated/network/qgsnetworkaccessmanager.sip.in @@ -284,7 +284,7 @@ If set to 0, no timeout is set. .. versionadded:: 3.6 %End - static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = 0 ); + static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = 0, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() ); %Docstring Posts a GET request to obtain the contents of the target request and returns a new :py:class:`QgsNetworkReplyContent` object for reading. The @@ -308,12 +308,14 @@ requests. The contents of the reply will be returned after the request is completed or an error occurs. +The ``flags`` argument was added in QGIS 4.0. + .. seealso:: :py:func:`blockingPost` .. versionadded:: 3.6 %End - static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = 0 ); + static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = 0, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() ); %Docstring Posts a POST request to obtain the contents of the target ``request``, using the given ``data``, and returns a new @@ -338,6 +340,8 @@ requests. The contents of the reply will be returned after the request is completed or an error occurs. +The ``flags`` argument was added in QGIS 4.0. + .. seealso:: :py:func:`blockingGet` .. versionadded:: 3.6 diff --git a/python/PyQt6/core/auto_generated/qgis.sip.in b/python/PyQt6/core/auto_generated/qgis.sip.in index 35916703694..c4cbefcb687 100644 --- a/python/PyQt6/core/auto_generated/qgis.sip.in +++ b/python/PyQt6/core/auto_generated/qgis.sip.in @@ -121,6 +121,14 @@ The development version NoLevel, }; + enum class NetworkRequestFlag /BaseType=IntFlag/ + { + DisableMessageLogging, + }; + + typedef QFlags NetworkRequestFlags; + + enum class LayerType /BaseType=IntEnum/ { Vector, @@ -3553,6 +3561,8 @@ PROJ4 string that represents a geographic coord system. }; +QFlags operator|(Qgis::NetworkRequestFlag f1, QFlags f2); + QFlags operator|(Qgis::AnnotationItemFlag f1, QFlags f2); QFlags operator|(Qgis::AnnotationItemGuiFlag f1, QFlags f2); diff --git a/python/core/auto_additions/qgis.py b/python/core/auto_additions/qgis.py index 60d83aa182f..6b89d91a13d 100644 --- a/python/core/auto_additions/qgis.py +++ b/python/core/auto_additions/qgis.py @@ -69,6 +69,19 @@ Qgis.AuthConfigurationStorageCapability.baseClass = Qgis Qgis.AuthConfigurationStorageCapabilities.baseClass = Qgis AuthConfigurationStorageCapabilities = Qgis # dirty hack since SIP seems to introduce the flags in module Qgis.MessageLevel.baseClass = Qgis +# monkey patching scoped based enum +Qgis.NetworkRequestFlag.DisableMessageLogging.__doc__ = "If present, indicates that no message logging should be performed when network errors are encountered" +Qgis.NetworkRequestFlag.__doc__ = """Flags controlling behavior of network requests. + +.. versionadded:: 4.0 + +* ``DisableMessageLogging``: If present, indicates that no message logging should be performed when network errors are encountered + +""" +# -- +Qgis.NetworkRequestFlag.baseClass = Qgis +Qgis.NetworkRequestFlags.baseClass = Qgis +NetworkRequestFlags = Qgis # dirty hack since SIP seems to introduce the flags in module QgsMapLayer.LayerType = Qgis.LayerType # monkey patching scoped based enum QgsMapLayer.VectorLayer = Qgis.LayerType.Vector diff --git a/python/core/auto_generated/network/qgsblockingnetworkrequest.sip.in b/python/core/auto_generated/network/qgsblockingnetworkrequest.sip.in index b0866c05d28..3d410071b3c 100644 --- a/python/core/auto_generated/network/qgsblockingnetworkrequest.sip.in +++ b/python/core/auto_generated/network/qgsblockingnetworkrequest.sip.in @@ -50,13 +50,22 @@ copy and pass between threads without issue. typedef QFlags RequestFlags; - explicit QgsBlockingNetworkRequest(); + explicit QgsBlockingNetworkRequest( Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() ); %Docstring -Constructor for QgsBlockingNetworkRequest +Constructor for QgsBlockingNetworkRequest. + +The ``flags`` argument was added in QGIS 4.0 %End ~QgsBlockingNetworkRequest(); + Qgis::NetworkRequestFlags flags() const; +%Docstring +Returns the network request flags. + +.. versionadded:: 4.0 +%End + ErrorCode get( QNetworkRequest &request, bool forceRefresh = false, QgsFeedback *feedback = 0, RequestFlags requestFlags = QgsBlockingNetworkRequest::RequestFlags() ); %Docstring Performs a "get" operation on the specified ``request``. diff --git a/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in b/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in index b40c93f41f3..38e2787412e 100644 --- a/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in +++ b/python/core/auto_generated/network/qgsnetworkaccessmanager.sip.in @@ -284,7 +284,7 @@ If set to 0, no timeout is set. .. versionadded:: 3.6 %End - static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = 0 ); + static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = 0, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() ); %Docstring Posts a GET request to obtain the contents of the target request and returns a new :py:class:`QgsNetworkReplyContent` object for reading. The @@ -308,12 +308,14 @@ requests. The contents of the reply will be returned after the request is completed or an error occurs. +The ``flags`` argument was added in QGIS 4.0. + .. seealso:: :py:func:`blockingPost` .. versionadded:: 3.6 %End - static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = 0 ); + static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = 0, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() ); %Docstring Posts a POST request to obtain the contents of the target ``request``, using the given ``data``, and returns a new @@ -338,6 +340,8 @@ requests. The contents of the reply will be returned after the request is completed or an error occurs. +The ``flags`` argument was added in QGIS 4.0. + .. seealso:: :py:func:`blockingGet` .. versionadded:: 3.6 diff --git a/python/core/auto_generated/qgis.sip.in b/python/core/auto_generated/qgis.sip.in index 50a766b62f4..f0b3063e38c 100644 --- a/python/core/auto_generated/qgis.sip.in +++ b/python/core/auto_generated/qgis.sip.in @@ -121,6 +121,14 @@ The development version NoLevel, }; + enum class NetworkRequestFlag + { + DisableMessageLogging, + }; + + typedef QFlags NetworkRequestFlags; + + enum class LayerType { Vector, @@ -3553,6 +3561,8 @@ PROJ4 string that represents a geographic coord system. }; +QFlags operator|(Qgis::NetworkRequestFlag f1, QFlags f2); + QFlags operator|(Qgis::AnnotationItemFlag f1, QFlags f2); QFlags operator|(Qgis::AnnotationItemGuiFlag f1, QFlags f2); diff --git a/src/core/network/qgsblockingnetworkrequest.cpp b/src/core/network/qgsblockingnetworkrequest.cpp index b91a4d369b1..029d1f91b2f 100644 --- a/src/core/network/qgsblockingnetworkrequest.cpp +++ b/src/core/network/qgsblockingnetworkrequest.cpp @@ -31,7 +31,8 @@ #include #include -QgsBlockingNetworkRequest::QgsBlockingNetworkRequest() +QgsBlockingNetworkRequest::QgsBlockingNetworkRequest( Qgis::NetworkRequestFlags flags ) + : mFlags( flags ) { connect( QgsNetworkAccessManager::instance(), qOverload< QNetworkReply * >( &QgsNetworkAccessManager::requestTimedOut ), this, &QgsBlockingNetworkRequest::requestTimedOut ); } @@ -146,7 +147,10 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( Qgis: { mErrorCode = NetworkError; mErrorMessage = errorMessageFailedAuth(); - QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + if ( !mFlags.testFlag( Qgis::NetworkRequestFlag::DisableMessageLogging ) ) + { + QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + } return NetworkError; } @@ -186,7 +190,10 @@ QgsBlockingNetworkRequest::ErrorCode QgsBlockingNetworkRequest::doRequest( Qgis: { mErrorCode = NetworkError; mErrorMessage = errorMessageFailedAuth(); - QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + if ( !mFlags.testFlag( Qgis::NetworkRequestFlag::DisableMessageLogging ) ) + { + QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + } if ( requestMadeFromMainThread ) authRequestBufferNotEmpty.wakeAll(); success = false; @@ -353,7 +360,10 @@ void QgsBlockingNetworkRequest::replyFinished() if ( toUrl == mReply->url() ) { mErrorMessage = tr( "Redirect loop detected: %1" ).arg( toUrl.toString() ); - QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + if ( !mFlags.testFlag( Qgis::NetworkRequestFlag::DisableMessageLogging ) ) + { + QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + } mReplyContent.clear(); } else @@ -365,7 +375,10 @@ void QgsBlockingNetworkRequest::replyFinished() mReplyContent.clear(); mErrorMessage = errorMessageFailedAuth(); mErrorCode = NetworkError; - QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + if ( !mFlags.testFlag( Qgis::NetworkRequestFlag::DisableMessageLogging ) ) + { + QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + } emit finished(); Q_NOWARN_DEPRECATED_PUSH emit downloadFinished(); @@ -396,7 +409,10 @@ void QgsBlockingNetworkRequest::replyFinished() mReplyContent.clear(); mErrorMessage = errorMessageFailedAuth(); mErrorCode = NetworkError; - QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + if ( !mFlags.testFlag( Qgis::NetworkRequestFlag::DisableMessageLogging ) ) + { + QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + } emit finished(); Q_NOWARN_DEPRECATED_PUSH emit downloadFinished(); @@ -455,7 +471,10 @@ void QgsBlockingNetworkRequest::replyFinished() { mErrorMessage = tr( "empty response: %1" ).arg( mReply->errorString() ); mErrorCode = ServerExceptionError; - QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + if ( !mFlags.testFlag( Qgis::NetworkRequestFlag::DisableMessageLogging ) ) + { + QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + } } mReplyContent.setContent( content ); } @@ -466,7 +485,10 @@ void QgsBlockingNetworkRequest::replyFinished() { mErrorMessage = mReply->errorString(); mErrorCode = ServerExceptionError; - QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + if ( !mFlags.testFlag( Qgis::NetworkRequestFlag::DisableMessageLogging ) ) + { + QgsMessageLog::logMessage( mErrorMessage, tr( "Network" ) ); + } } mReplyContent = QgsNetworkReplyContent( mReply ); mReplyContent.setContent( mReply->readAll() ); diff --git a/src/core/network/qgsblockingnetworkrequest.h b/src/core/network/qgsblockingnetworkrequest.h index 563273ab3da..142cd0fd677 100644 --- a/src/core/network/qgsblockingnetworkrequest.h +++ b/src/core/network/qgsblockingnetworkrequest.h @@ -71,11 +71,22 @@ class CORE_EXPORT QgsBlockingNetworkRequest : public QObject Q_DECLARE_FLAGS( RequestFlags, RequestFlag ) Q_FLAG( RequestFlags ) - //! Constructor for QgsBlockingNetworkRequest - explicit QgsBlockingNetworkRequest(); + /** + * Constructor for QgsBlockingNetworkRequest. + * + * The \a flags argument was added in QGIS 4.0 + */ + explicit QgsBlockingNetworkRequest( Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() ); ~QgsBlockingNetworkRequest() override; + /** + * Returns the network request flags. + * + * \since QGIS 4.0 + */ + Qgis::NetworkRequestFlags flags() const { return mFlags; } + /** * Performs a "get" operation on the specified \a request. * @@ -258,6 +269,8 @@ class CORE_EXPORT QgsBlockingNetworkRequest : public QObject private : + Qgis::NetworkRequestFlags mFlags; + //! The reply to the request QNetworkReply *mReply = nullptr; diff --git a/src/core/network/qgsnetworkaccessmanager.cpp b/src/core/network/qgsnetworkaccessmanager.cpp index f9c99df2c11..618e3a70ef2 100644 --- a/src/core/network/qgsnetworkaccessmanager.cpp +++ b/src/core/network/qgsnetworkaccessmanager.cpp @@ -801,17 +801,17 @@ void QgsNetworkAccessManager::setTimeout( const int time ) settingsNetworkTimeout->setValue( time ); } -QgsNetworkReplyContent QgsNetworkAccessManager::blockingGet( QNetworkRequest &request, const QString &authCfg, bool forceRefresh, QgsFeedback *feedback ) +QgsNetworkReplyContent QgsNetworkAccessManager::blockingGet( QNetworkRequest &request, const QString &authCfg, bool forceRefresh, QgsFeedback *feedback, Qgis::NetworkRequestFlags flags ) { - QgsBlockingNetworkRequest br; + QgsBlockingNetworkRequest br( flags ); br.setAuthCfg( authCfg ); br.get( request, forceRefresh, feedback ); return br.reply(); } -QgsNetworkReplyContent QgsNetworkAccessManager::blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg, bool forceRefresh, QgsFeedback *feedback ) +QgsNetworkReplyContent QgsNetworkAccessManager::blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg, bool forceRefresh, QgsFeedback *feedback, Qgis::NetworkRequestFlags flags ) { - QgsBlockingNetworkRequest br; + QgsBlockingNetworkRequest br( flags ); br.setAuthCfg( authCfg ); br.post( request, data, forceRefresh, feedback ); return br.reply(); diff --git a/src/core/network/qgsnetworkaccessmanager.h b/src/core/network/qgsnetworkaccessmanager.h index 07893ed92cd..460ffabf4fd 100644 --- a/src/core/network/qgsnetworkaccessmanager.h +++ b/src/core/network/qgsnetworkaccessmanager.h @@ -477,10 +477,12 @@ class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager * * The contents of the reply will be returned after the request is completed or an error occurs. * + * The \a flags argument was added in QGIS 4.0. + * * \see blockingPost() * \since QGIS 3.6 */ - static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr ); + static QgsNetworkReplyContent blockingGet( QNetworkRequest &request, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() ); /** * Posts a POST request to obtain the contents of the target \a request, using the given \a data, and returns a new @@ -499,10 +501,12 @@ class CORE_EXPORT QgsNetworkAccessManager : public QNetworkAccessManager * * The contents of the reply will be returned after the request is completed or an error occurs. * + * The \a flags argument was added in QGIS 4.0. + * * \see blockingGet() * \since QGIS 3.6 */ - static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr ); + static QgsNetworkReplyContent blockingPost( QNetworkRequest &request, const QByteArray &data, const QString &authCfg = QString(), bool forceRefresh = false, QgsFeedback *feedback = nullptr, Qgis::NetworkRequestFlags flags = Qgis::NetworkRequestFlags() ); /** * Sets a request pre-processor function, which allows manipulation of a network request before it is processed. diff --git a/src/core/qgis.h b/src/core/qgis.h index 537ba8401e1..1d32e765117 100644 --- a/src/core/qgis.h +++ b/src/core/qgis.h @@ -161,6 +161,25 @@ class CORE_EXPORT Qgis }; Q_ENUM( MessageLevel ) + /** + * \brief Flags controlling behavior of network requests. + * + * \since QGIS 4.0 + */ + enum class NetworkRequestFlag : int SIP_ENUM_BASETYPE( IntFlag ) + { + DisableMessageLogging = 1 << 0, //!< If present, indicates that no message logging should be performed when network errors are encountered + }; + Q_ENUM( NetworkRequestFlag ) + + /** + * \brief Flags controlling behavior of network requests. + * + * \since QGIS 3.40 + */ + Q_DECLARE_FLAGS( NetworkRequestFlags, NetworkRequestFlag ) + Q_FLAG( NetworkRequestFlags ) + /** * Types of layers that can be added to a map * @@ -6236,6 +6255,7 @@ class CORE_EXPORT Qgis QHASH_FOR_CLASS_ENUM( Qgis::CaptureTechnique ) QHASH_FOR_CLASS_ENUM( Qgis::RasterAttributeTableFieldUsage ) +Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::NetworkRequestFlags ) Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::AnnotationItemFlags ) Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::AnnotationItemGuiFlags ) Q_DECLARE_OPERATORS_FOR_FLAGS( Qgis::AuthConfigurationStorageCapabilities )