brutasse / graphite-cyanite

A plugin for using graphite-web with the cassandra-based Cyanite storage backend.
BSD 3-Clause "New" or "Revised" License
85 stars 21 forks source link

'NoneType' object if no data found #17

Closed hryamzik closed 8 years ago

hryamzik commented 8 years ago

If there's no data for some metric grafana shows the following error:

Traceback (most recent call last): File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app response = self.full_dispatch_request() File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1477, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1381, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request rv = self.dispatch_request() File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/usr/local/lib/python2.7/dist-packages/graphite_api/app.py", line 401, in render series_list = evaluateTarget(context, target, data_store) File "/usr/local/lib/python2.7/dist-packages/graphite_api/app.py", line 496, in evaluateTarget result = evaluateTokens(requestContext, tokens, data_store) File "/usr/local/lib/python2.7/dist-packages/graphite_api/app.py", line 506, in evaluateTokens return evaluateTokens(requestContext, tokens.expression, data_store) File "/usr/local/lib/python2.7/dist-packages/graphite_api/app.py", line 509, in evaluateTokens return data_store.get_series_list(tokens.pathExpression) File "/usr/local/lib/python2.7/dist-packages/graphite_api/render/datalib.py", line 121, in get_series_list for data in self.data.get(path): TypeError: 'NoneType' object is not iterable

I've debugged this a bit and here's the request that returns "None': self.get_paths(path_expr):

    def get_series_list(self, path_expr):
        series_list = []
        for path in self.get_paths(path_expr):
            for data in self.data.get(path):
                start, end, step = data['time_info']
                series = TimeSeries(path, start, end, step, data['values'])
                series.pathExpression = path_expr
                series_list.append(series)
        return series_list

What's the propper return value in this case?

hryamzik commented 8 years ago

In fact this could be hot fixed by modifying the function as follows:

    def get_series_list(self, path_expr):
        series_list = []
        for path in self.get_paths(path_expr):
            try:
                for data in self.data.get(path):
                    start, end, step = data['time_info']
                    series = TimeSeries(path, start, end, step, data['values'])
                    series.pathExpression = path_expr
                    series_list.append(series)
            except Exception as e:
                import traceback
                logger.error(traceback.format_exc())
        return series_list

But looks like the propper way is to return an empty array from cyanite code.

brutasse commented 8 years ago

@hryamzik do you use graphite-api 1.1 installed with pip? There have been two commits since the release related to an issue that looks similar. Could you try with the latest master version?

hryamzik commented 8 years ago

@brutasse tried to reinstall with pip install --upgrade git+https://github.com/brutasse/graphite-cyanite.git#egg=cyanite – still the same error.

brutasse commented 8 years ago

@hryamzik can you try the same with graphite-api?

hryamzik commented 8 years ago

@brutasse it works, thanks! I'll replace pip installs with github ones...

brutasse commented 8 years ago

Great! I'll make a proper release soon :)

hryamzik commented 8 years ago

So I'm closing this. @brutasse could I possibly ask you to look at #16 as well?