Ribbit-Network / ribbit-network-dashboard

The web dashboard for the world's largest crowdsourced network of open-source, low-cost, CO2 Gas Detection Sensors.
MIT License
17 stars 16 forks source link

Error Loading Layout #50

Closed keenanjohnson closed 2 years ago

keenanjohnson commented 2 years ago

@spestana reported the following error on the webpage:

"Just now I was refreshing the dashboard page (I had to re-route some power cords outside so was waiting to see if my frog was reconnected yet), and encountered an "Error loading layout" message on the dashboard site. A couple of page refreshes and it goes away. But then it comes back again sometimes?"

image

He noticed that his console showed the following local log:

image

I looked at the Heroku console and saw the following:

2021-10-05T22:44:55.823116+00:00 heroku[router]: at=info method=POST path="/_dash-update-component" host=ribbit-network.herokuapp.com request_id=201028a8-8ad1-40a1-ac1d-0b48142720d7 fwd="70.122.146.96" dyno=web.1 connect=0ms service=111ms status=500 bytes=463 protocol=https
2021-10-05T22:44:56.002517+00:00 heroku[router]: at=info method=POST path="/_dash-update-component" host=ribbit-network.herokuapp.com request_id=034d20dc-30ea-4947-84f2-82092fa9e465 fwd="70.122.146.96" dyno=web.1 connect=0ms service=446ms status=200 bytes=75648 protocol=https
2021-10-05T22:44:55.821473+00:00 app[web.1]: Exception on /_dash-update-component [POST]
2021-10-05T22:44:55.821478+00:00 app[web.1]: Traceback (most recent call last):
2021-10-05T22:44:55.821479+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 2070, in wsgi_app
2021-10-05T22:44:55.821479+00:00 app[web.1]:     response = self.full_dispatch_request()
2021-10-05T22:44:55.821480+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1515, in full_dispatch_request
2021-10-05T22:44:55.821480+00:00 app[web.1]:     rv = self.handle_user_exception(e)
2021-10-05T22:44:55.821481+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1513, in full_dispatch_request
2021-10-05T22:44:55.821481+00:00 app[web.1]:     rv = self.dispatch_request()
2021-10-05T22:44:55.821481+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/flask/app.py", line 1499, in dispatch_request
2021-10-05T22:44:55.821482+00:00 app[web.1]:     return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
2021-10-05T22:44:55.821482+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/dash/dash.py", line 1079, in dispatch
2021-10-05T22:44:55.821483+00:00 app[web.1]:     response.set_data(func(*args, outputs_list=outputs_list))
2021-10-05T22:44:55.821483+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/dash/dash.py", line 1010, in add_context
2021-10-05T22:44:55.821484+00:00 app[web.1]:     output_value = func(*args, **kwargs)  # %% callback invoked %%
2021-10-05T22:44:55.821484+00:00 app[web.1]:   File "/app/app.py", line 188, in update_map
2021-10-05T22:44:55.821485+00:00 app[web.1]:     df = db.get_map_data()
2021-10-05T22:44:55.821485+00:00 app[web.1]:   File "/app/db.py", line 15, in get_map_data
2021-10-05T22:44:55.821485+00:00 app[web.1]:     return pd.concat(df)
2021-10-05T22:44:55.821485+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/pandas/core/reshape/concat.py", line 285, in concat
2021-10-05T22:44:55.821486+00:00 app[web.1]:     op = _Concatenator(
2021-10-05T22:44:55.821486+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.9/site-packages/pandas/core/reshape/concat.py", line 320, in __init__
2021-10-05T22:44:55.821486+00:00 app[web.1]:     raise TypeError(
2021-10-05T22:44:55.821486+00:00 app[web.1]: TypeError: first argument must be an iterable of pandas objects, you passed an object of type "DataFrame"
keenanjohnson commented 2 years ago

Here's the full error trace file for reference: ribbit-network-logs-1633473915601.txt

spestana commented 2 years ago

It looks like it breaks when the db query returns a single dataframe, rather than a list of dataframes? https://github.com/Ribbit-Network/ribbit-network-dashboard/blob/e3ae765f38680bf51ec544383455cf85b91b4ed9/db.py#L9

spestana commented 2 years ago

A fix could be as simple as forcing any dataframe that's returned by itself into a list (e.g. pd.concat(df) to pd.concat([df])) but why does the function query_api.query_data_frame() return a dataframe sometimes, and a list of dataframes other times? Because there are multiple tables in the db?

Help on method query_data_frame in module influxdb_client.client.query_api:

query_data_frame(query: str, org=None, data_frame_index: List[str] = None, params: dict = None) method of influxdb_client.client.query_api.QueryApi instance
    Execute synchronous Flux query and return Pandas DataFrame.

    Note that if a query returns more then one table than the client generates a DataFrame for each of them.

    :param query: the Flux query
    :param str, Organization org: specifies the organization for executing the query;
                                  take the ID, Name or Organization;
                                  if it's not specified then is used default from client.org.
    :param data_frame_index: the list of columns that are used as DataFrame index
    :param params: bind parameters
    :return:
keenanjohnson commented 2 years ago

Yeah that is weird. Seems like a poor way to design an API on the InfluxDB side IMO haha.