Skip to content
Permalink
Browse files

Merge pull request #8922 from mhugent/server_datasource_error

Server: catch datasource error
  • Loading branch information
mhugent committed Jan 24, 2019
2 parents c90905b + 9eeaa31 commit b5febe5189504f4ed243b2dffc159028a6bef6d2
@@ -567,6 +567,13 @@ in the area of the map item covered by the item.
.. seealso:: :py:func:`removeLabelBlockingItem`

.. versionadded:: 3.6
%End

QgsMapRendererJob::Errors renderingErrors() const;
%Docstring
Returns map rendering errors

:return: list of errors
%End

protected:
@@ -0,0 +1,52 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/server/qgsstorebadlayerinfo.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/




class QgsStoreBadLayerInfo: QgsProjectBadLayerHandler
{
%Docstring
Stores layer ids of bad layers

.. versionadded:: 3.6
%End

%TypeHeaderCode
#include "qgsstorebadlayerinfo.h"
%End
public:

QgsStoreBadLayerInfo();
%Docstring
Default constructor
%End

void handleBadLayers( const QList<QDomNode> &layers );
%Docstring
handleBadLayers

:param layers: layer nodes
%End

QStringList badLayers() const;
%Docstring
badLayers

:return: ids of bad layers
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/server/qgsstorebadlayerinfo.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
@@ -22,6 +22,7 @@
%Include auto_generated/qgsserviceregistry.sip
%Include auto_generated/qgsfeaturefilterprovidergroup.sip
%Include auto_generated/qgsfeaturefilter.sip
%Include auto_generated/qgsstorebadlayerinfo.sip
%If ( HAVE_SERVER_PYTHON_PLUGINS )
%Include auto_generated/qgsserverfilter.sip
%End
@@ -1021,6 +1021,8 @@ void QgsLayoutItemMap::drawMap( QPainter *painter, const QgsRectangle &extent, Q
// with printing to printer on Windows (printing to PDF is fine though).
// Raster images were not displayed - see #10599
job.renderSynchronously();

mRenderingErrors = job.errors();
}

void QgsLayoutItemMap::recreateCachedImageInBackground()
@@ -511,6 +511,12 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
*/
bool isLabelBlockingItem( QgsLayoutItem *item ) const;

/**
* \brief Returns map rendering errors
* \returns list of errors
*/
QgsMapRendererJob::Errors renderingErrors() const { return mRenderingErrors; }

protected:

void draw( QgsLayoutItemRenderContext &context ) override;
@@ -726,6 +732,9 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
QStringList mBlockingLabelItemUuids;
QList< QPointer< QgsLayoutItem > > mBlockingLabelItems;

//!layer id / error message
QgsMapRendererJob::Errors mRenderingErrors;

void init();

//! Resets the item tooltip to reflect current map id
@@ -55,6 +55,7 @@ struct LayerRenderJob
bool cached; // if true, img already contains cached image from previous rendering
QgsWeakMapLayerPointer layer;
int renderingTime; //!< Time it took to render the layer in ms (it is -1 if not rendered or still rendering)
QStringList errors; //!< Rendering errors
};

typedef QList<LayerRenderJob> LayerRenderJobs;
@@ -195,6 +195,15 @@ void QgsMapRendererParallelJob::renderLayersFinished()
{
Q_ASSERT( mStatus == RenderingLayers );

LayerRenderJobs::const_iterator it = mLayerJobs.constBegin();
for ( ; it != mLayerJobs.constEnd(); ++it )
{
if ( !it->errors.isEmpty() )
{
mErrors.append( Error( it->layer->id(), it->errors.join( ',' ) ) );
}
}

// compose final image
mFinalImage = composeImage( mSettings, mLayerJobs, mLabelJob );

@@ -269,6 +278,8 @@ void QgsMapRendererParallelJob::renderLayerStatic( LayerRenderJob &job )
{
QgsDebugMsg( QStringLiteral( "Caught unhandled unknown exception" ) );
}

job.errors = job.renderer->errors();
job.renderingTime += t.elapsed();
QgsDebugMsgLevel( QStringLiteral( "job %1 end [%2 ms] (layer %3)" ).arg( reinterpret_cast< quint64 >( &job ), 0, 16 ).arg( job.renderingTime ).arg( job.layer ? job.layer->id() : QString() ), 2 );
}
@@ -246,6 +246,11 @@ bool QgsVectorLayerRenderer::render()
else
drawRenderer( fit );

if ( !fit.isValid() )
{
mErrors.append( QStringLiteral( "Data source invalid" ) );
}

if ( usingEffect )
{
mRenderer->paintEffect()->end( mContext );
@@ -47,8 +47,9 @@ QgsPostgresFeatureIterator::QgsPostgresFeatureIterator( QgsPostgresFeatureSource
mIsTransactionConnection = true;
}

if ( !mConn )
if ( !mConn || mConn->PQstatus() != CONNECTION_OK )
{
mValid = false;
mClosed = true;
iteratorClosed();
return;
@@ -40,6 +40,7 @@ SET(QGIS_SERVER_SRCS
qgsserviceregistry.cpp
qgsfeaturefilterprovidergroup.cpp
qgsfeaturefilter.cpp
qgsstorebadlayerinfo.cpp
)

SET (QGIS_SERVER_HDRS
@@ -17,6 +17,8 @@

#include "qgsconfigcache.h"
#include "qgsmessagelog.h"
#include "qgsserverexception.h"
#include "qgsstorebadlayerinfo.h"

#include <QFile>

@@ -40,8 +42,16 @@ const QgsProject *QgsConfigCache::project( const QString &path )
if ( ! mProjectCache[ path ] )
{
std::unique_ptr<QgsProject> prj( new QgsProject() );
QgsStoreBadLayerInfo *badLayerHandler = new QgsStoreBadLayerInfo();
prj->setBadLayerHandler( badLayerHandler );
if ( prj->read( path ) )
{
if ( !badLayerHandler->badLayers().isEmpty() )
{
QString errorMsg = QStringLiteral( "Layer(s) %1 not valid" ).arg( badLayerHandler->badLayers().join( ',' ) );
QgsMessageLog::logMessage( errorMsg, QStringLiteral( "Server" ), Qgis::Critical );
throw QgsServerException( QStringLiteral( "Layer(s) not valid" ) );
}
mProjectCache.insert( path, prj.release() );
mFileSystemWatcher.addPath( path );
}
@@ -0,0 +1,36 @@
/***************************************************************************
qgsstorebadlayerinfo.cpp
------------------------
begin : Jan 2019
copyright : (C) 2019 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsstorebadlayerinfo.h"
#include <QDomElement>

void QgsStoreBadLayerInfo::handleBadLayers( const QList<QDomNode> &layers )
{
mBadLayerIds.clear();
QList<QDomNode>::const_iterator it = layers.constBegin();
for ( ; it != layers.constEnd(); ++it )
{
if ( !it->isNull() )
{
QDomElement idElem = it->firstChildElement( "id" );
if ( !idElem.isNull() )
{
mBadLayerIds.append( idElem.text() );
}
}
}
}
@@ -0,0 +1,55 @@
/***************************************************************************
qgsstorebadlayerinfo.h
----------------------
begin : Jan 2019
copyright : (C) 2019 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSSTOREBADLAYERINFO_H
#define QGSSTOREBADLAYERINFO_H

#include "qgsprojectbadlayerhandler.h"
#include "qgis_server.h"
#include <QStringList>

/**
* \ingroup server
* Stores layer ids of bad layers
* \since QGIS 3.6
*/
class SERVER_EXPORT QgsStoreBadLayerInfo: public QgsProjectBadLayerHandler
{
public:

/**
* Default constructor
*/
QgsStoreBadLayerInfo() = default;

/**
* \brief handleBadLayers
* \param layers layer nodes
*/
void handleBadLayers( const QList<QDomNode> &layers );

/**
* \brief badLayers
* \returns ids of bad layers
*/
QStringList badLayers() const { return mBadLayerIds; }

private:
QStringList mBadLayerIds;
};

#endif // QGSSTOREBADLAYERINFO_H
@@ -67,6 +67,8 @@ namespace QgsWms
renderJob.waitForFinished();
*image = renderJob.renderedImage();
mPainter.reset( new QPainter( image ) );

mErrors = renderJob.errors();
}
else
{
@@ -76,12 +78,12 @@ namespace QgsWms
renderJob.setFeatureFilterProvider( mFeatureFilterProvider );
#endif
renderJob.renderSynchronously();
mErrors = renderJob.errors();
}
}

QPainter *QgsMapRendererJobProxy::takePainter()
{
return mPainter.release();
}

} // namespace qgsws
@@ -19,6 +19,7 @@
#define QGSMAPRENDERERJOBPROXY_H

#include "qgsmapsettings.h"
#include "qgsmaprendererjob.h"

class QgsFeatureFilterProvider;

@@ -61,10 +62,21 @@ namespace QgsWms
*/
QPainter *takePainter();

/**
* \brief Returns map rendering errors
* \returns error list
*/
QgsMapRendererJob::Errors errors() const { return mErrors; }

private:
bool mParallelRendering;
QgsFeatureFilterProvider *mFeatureFilterProvider = nullptr;
std::unique_ptr<QPainter> mPainter;

void getRenderErrors( const QgsMapRendererJob *job );

//! Layer id / error message
QgsMapRendererJob::Errors mErrors;
};


0 comments on commit b5febe5

Please sign in to comment.
You can’t perform that action at this time.