diff --git a/lizmap/modules/lizmap/lib/Request/OGCRequest.php b/lizmap/modules/lizmap/lib/Request/OGCRequest.php
index 5093b92b3d..ee32f39dae 100644
--- a/lizmap/modules/lizmap/lib/Request/OGCRequest.php
+++ b/lizmap/modules/lizmap/lib/Request/OGCRequest.php
@@ -185,6 +185,78 @@ protected function constructUrl()
return Proxy::constructUrl($this->parameters(), $this->services, $url);
}
+ /**
+ * Generate a string to identify the target of the HTTP request.
+ *
+ * @param array $parameters The list of HTTP parameters in the query
+ * @param int $code The HTTP code of the request
+ *
+ * @return string The string to identify the HTTP request, with main OGC parameters first such as MAP, SERVICE...
+ */
+ private function formatHttpErrorString($parameters, $code)
+ {
+ // Clone parameters array to perform unset without modify it
+ $params = array_merge(array(), $parameters);
+
+ // Ordered list of params to fetch first
+ $mainParamsToLog = array('map', 'repository', 'project', 'service', 'request');
+
+ $output = array();
+ foreach ($mainParamsToLog as $paramName) {
+ if (array_key_exists($paramName, $params)) {
+ $output[] = '"'.strtoupper($paramName).'" = '."'".$params[$paramName]."'";
+ unset($params[$paramName]);
+ }
+ }
+
+ // First implode with main parameters
+ $message = implode(' & ', $output);
+
+ if ($params) {
+ // Ideally, we want two lines, one with main parameters, the second one with secondary parameters
+ // It does not work in jLog
+ // $message .= '\n';
+ $message .= ' & ';
+ }
+
+ // For remaining parameters in the array, which are not in the main list
+ $output = array();
+ foreach ($params as $key => $value) {
+ $output[] = '"'.strtoupper($key).'" = '."'".$value."'";
+ }
+
+ $message .= implode(' & ', $output);
+
+ return 'HTTP code '.$code.' on '.$message;
+ }
+
+ /**
+ * Log if the HTTP code is a 4XX or 5XX error code.
+ *
+ * @param int $code The HTTP code of the request
+ */
+ protected function logRequestIfError($code)
+ {
+ if ($code < 400) {
+ return;
+ }
+
+ $message = 'The HTTP OGC request to QGIS Server ended with an error.';
+
+ // The master error with MAP parameter
+ // This user must have an access to QGIS Server logs
+ $params = $this->parameters();
+ \jLog::log($message.' Check logs on QGIS Server. '.$this->formatHttpErrorString($params, $code), 'error');
+
+ // The admin error without the MAP parameter
+ // but replaced by REPOSITORY and PROJECT parameters
+ // This user might not have an access to QGIS Server logs
+ unset($params['map']);
+ $params['repository'] = $this->project->getRepository()->getKey();
+ $params['project'] = $this->project->getKey();
+ \jLog::log($message.' '.$this->formatHttpErrorString($params, $code), 'lizmapadmin');
+ }
+
/**
* Request QGIS Server.
*
@@ -236,11 +308,15 @@ protected function request($post = false, $stream = false)
if ($stream) {
$response = \Lizmap\Request\Proxy::getRemoteDataAsStream($querystring, $options);
+ $this->logRequestIfError($response->getCode());
+
return new OGCResponse($response->getCode(), $response->getMime(), $response->getBodyAsStream());
}
list($data, $mime, $code) = \Lizmap\Request\Proxy::getRemoteData($querystring, $options);
+ $this->logRequestIfError($code);
+
return new OGCResponse($code, $mime, $data);
}
diff --git a/lizmap/modules/lizmap/lib/Request/Proxy.php b/lizmap/modules/lizmap/lib/Request/Proxy.php
index 5a912b72f5..de3d433e1f 100644
--- a/lizmap/modules/lizmap/lib/Request/Proxy.php
+++ b/lizmap/modules/lizmap/lib/Request/Proxy.php
@@ -489,14 +489,14 @@ protected static function fileProxy($url, $options)
* @param int $httpCode The HTTP code of the request
* @param string $url The URL of the request, for logging
*/
- public static function logRequestIfError($httpCode, $url)
+ protected static function logRequestIfError($httpCode, $url)
{
- $httpCodeClass = substr($httpCode, 0, 1);
- // Change to str_starts_with when PHP 8.1 will be minimum version for all maintained version
- if ($httpCodeClass == '4' || $httpCodeClass == '5') {
- \jLog::log('An HTTP request ended with an error, please check the main error log. Code '.$httpCode, 'lizmapadmin');
- \jLog::log('The HTTP request below ended with an error. Code '.$httpCode.' → '.$url, 'error');
+ if ($httpCode < 400) {
+ return;
}
+
+ \jLog::log('An HTTP request ended with an error, please check the main error log. HTTP code '.$httpCode, 'lizmapadmin');
+ \jLog::log('The HTTP request ended with an error. HTTP code '.$httpCode.' → '.$url, 'error');
}
/**
diff --git a/lizmap/modules/view/locales/en_US/dictionnary.UTF-8.properties b/lizmap/modules/view/locales/en_US/dictionnary.UTF-8.properties
index b31e342c28..c6e52b4a84 100644
--- a/lizmap/modules/view/locales/en_US/dictionnary.UTF-8.properties
+++ b/lizmap/modules/view/locales/en_US/dictionnary.UTF-8.properties
@@ -1,6 +1,6 @@
startup.error=An error occurred while loading this map. Some necessary resources may temporarily be unavailable. Please try again later.
startup.error.administrator=Please notify the administrator of this map to connect and visit this map.
-startup.error.developer.tools=Maybe you will have a clue by opening your "Developer tools" in your web-browser. It's usually F12. Check "Console" and "Networks".
+startup.error.developer.tools=Maybe you will have a clue by opening your "Developer tools" in your web-browser. It's usually F12. Check "Console" and "Networks".\n\nVisit the administration panel and check in the log page if an HTTP request ended with an error related to this project.
startup.user_defined_js=This map contains some users additional JavaScript scripts. This can be the cause of this message, try disabling them.
startup.goToProject=Home
startup.goToRepositoryAdmin=Maps management page