3liz / qgis-lizmap-server-plugin

QGIS Server plugin for Lizmap
GNU General Public License v2.0
6 stars 6 forks source link

GetFeatureInfo method returns different output on the same request #82

Closed mind84 closed 1 month ago

mind84 commented 3 months ago

Hi!

We're working on Lizmap to improve the display of the related children popup (e.g. display children in the corresponding tab, if any).

We're facing a weird issue when the popup appears and this problem happens seemingly randomly.

To properly address the children to the correct tab, I'm using a div container added programmatically by the method Tooltip._generate_attribute_editor_relation, called when a relation is detected:

https://github.com/3liz/qgis-lizmap-server-plugin/blob/84a2a6d839a93261997ea7981576461151cb95f5/lizmap_server/tooltip.py#L142

In this div, attributes like layerId or relation name are added as node attribute in order to have a suitable DOM reference to address popup children.

Problem is that sometimes these attribute are filled in correctly and sometimes they are empty (even between two identical subsequent requests)

Here two output of the GetFeatureInfo request, first when attributes are filled and second with empty attriutes:

node_relation_success

node_relation_failure

We've done some debug on the plugin and seems that sometimes the method node.relation()

https://github.com/3liz/qgis-lizmap-server-plugin/blob/84a2a6d839a93261997ea7981576461151cb95f5/lizmap_server/tooltip.py#L143

returns an empty object

We cannot figure out what's going on since, as mentioned, the method acts differently on identical requests.

Simply load the following test project in a local Lizmap master branch:

children_in_tabs.qgs.zip

Anyway, the basic system information of the stack used to reproduce the issue is as follows:

Versions :

List of safeguards :
* Mode : normal * Allow parent folder : yes * Number of parent : 7 folder(s) * Prevent other drive : no * Prevent PG service : no * Prevent PG Auth DB : no * Force PG user&pass : no * Prevent ECW : no

Thanks!

@ghtmtt

mind84 commented 3 months ago

Hi @Gustry,

were you able to reproduce this behavior? I'm asking because I've seen some commits involving that part of code.

If, hypothetically, this happened in js code, I would say that the problem is related to some asynchronous method, which I imagine is not the case for py.

Thanks

Gustry commented 3 months ago

Hi, No, I didn't try to debug, I just added quickly some logs.

mind84 commented 2 months ago

Hi @Gustry!

I've made some progress.

During execution the else statement

    if isinstance(node, QgsAttributeEditorRelation):
        relation = node.relation()
        if relation:
            a += Tooltip._generate_attribute_editor_relation(
                node.label(), relation.id(), relation.referencingLayerId())
        else:
            # Ticket https://github.com/3liz/qgis-lizmap-server-plugin/issues/82
            LOGGER.warning(
                f"The node '{node.name()}::{node.label()}' cannot be processed for the tooltip "
                f"because the relation has not been found.")

is never reached because relation object is always defined, but it's not valid.

I've placed some logs inside the ifcondition:

            if relation:
                LOGGER.warning(f"referenced Layer {relation.referencedLayer()} ============")
                LOGGER.warning(f"referenced Layer Id {relation.referencedLayerId()} ============")
                LOGGER.warning(f"relation name {relation.name()} ============")
                LOGGER.warning(f"relation type {relation.type()} ============")
                LOGGER.warning(f"is valid {relation.isValid()} ============")
                LOGGER.warning(f"error? {relation.validationError()}")
                a += Tooltip._generate_attribute_editor_relation(
                    node.label(), relation.id(), relation.referencingLayerId())
            else:

and result is:

referenced Layer None ============
referenced Layer Id  ============
relation name  ============
relation type 0 ============
is valid False ============
error? Referencing layer not set

BUT

if we use the relation_manager instance instead of node.relation() method to get the relation instance (for testing purpose I hard coded the relation id), like so:


     if isinstance(node, QgsAttributeEditorRelation):
            relation = relation_manager.relation("birds_spot_area_id_natural_ar_id")

            #relation = node.relation()
            if relation:
                LOGGER.warning(f"referenced Layer {relation.referencedLayer()} ============")
                LOGGER.warning(f"referenced Layer Id {relation.referencedLayerId()} ============")
                LOGGER.warning(f"relation name {relation.name()} ============")
                LOGGER.warning(f"relation type {relation.type()} ============")
                LOGGER.warning(f"is valid {relation.isValid()} ============")
                LOGGER.warning(f"error? {relation.validationError()}")
                a += Tooltip._generate_attribute_editor_relation(
                    node.label(), relation.id(), relation.referencingLayerId())
            else:

the output seems OK and also the HTML on client:

referenced Layer <QgsVectorLayer: 'natural_areas' (postgres)> ============
referenced Layer Id natural_areas_8babd542_8324_458a_adf6_91dd0d06fe4a ============
relation name nat_areas_birds_spots ============
relation type 0 ============
is valid True ============
error? 

I don't know if the relation_manager instance can be used this way. Anyway, hope this could help!

Thanks!

Gustry commented 1 month ago

I remember this PR from my colleague @dmarteau and @rldhont https://github.com/qgis/QGIS/pull/33476

rldhont commented 1 month ago

@mind84 can check this :

if isinstance(node, QgsAttributeEditorRelation):
    node.init(relation_manager) # Initializes the relation from the id
    relation = node.relation()
Gustry commented 1 month ago

Fixed in version 2.10.1 with 6a4240041858883a83baad08012a0604b19c8873