mirror of https://github.com/grafana/grafana
Improve error handling for Graphite 0.9 and 1.0 (#32642)
parent
5e1d0a8851
commit
0d08928981
@ -0,0 +1,90 @@ |
||||
import { reduceError } from './utils'; |
||||
|
||||
const SAMPLE_500_PAGE = `<body style="background-color: #666666; color: black;">
|
||||
<center> |
||||
<h2 style='font-family: "Arial"'> |
||||
<p>Graphite encountered an unexpected error while handling your request.</p> |
||||
<p>Please contact your site administrator if the problem persists.</p> |
||||
</h2> |
||||
<br/> |
||||
<div style="width: 50%; text-align: center; font-family: monospace; background-color: black; font-weight: bold; color: #ff4422;"> |
||||
|
||||
</div> |
||||
|
||||
<div style="width: 70%; text-align: left; background-color: black; color: #44ff22; border: thin solid gray;"> |
||||
<pre> |
||||
Traceback (most recent call last): |
||||
File "/usr/lib/python2.7/dist-packages/django/core/handlers/base.py", line 112, in get_response |
||||
response = wrapped_callback(request, *callback_args, **callback_kwargs) |
||||
File "/var/lib/graphite/webapp/graphite/render/views.py", line 125, in renderView |
||||
seriesList = evaluateTarget(requestContext, target) |
||||
File "/var/lib/graphite/webapp/graphite/render/evaluator.py", line 10, in evaluateTarget |
||||
result = evaluateTokens(requestContext, tokens) |
||||
File "/var/lib/graphite/webapp/graphite/render/evaluator.py", line 21, in evaluateTokens |
||||
return evaluateTokens(requestContext, tokens.expression) |
||||
File "/var/lib/graphite/webapp/graphite/render/evaluator.py", line 27, in evaluateTokens |
||||
func = SeriesFunctions[tokens.call.func] |
||||
KeyError: u'aliasByNodde' |
||||
|
||||
</pre> |
||||
</div> |
||||
|
||||
</center> |
||||
`;
|
||||
|
||||
describe('Graphite utils', () => { |
||||
it('should reduce HTML based errors', () => { |
||||
const error = { |
||||
status: 500, |
||||
data: { |
||||
message: SAMPLE_500_PAGE, |
||||
}, |
||||
}; |
||||
|
||||
expect(reduceError(error)).toMatchObject({ |
||||
data: { |
||||
message: 'Graphite encountered an unexpected error while handling your request. KeyError: aliasByNodde', |
||||
}, |
||||
}); |
||||
}); |
||||
|
||||
it('should return original error for non-HTML 500 error pages', () => { |
||||
const error = { |
||||
status: 500, |
||||
data: { |
||||
message: 'ERROR MESSAGE', |
||||
}, |
||||
}; |
||||
|
||||
expect(reduceError(error)).toMatchObject({ |
||||
data: { |
||||
message: 'ERROR MESSAGE', |
||||
}, |
||||
}); |
||||
}); |
||||
|
||||
it('should return original error for non 500 errors', () => { |
||||
const error = { |
||||
status: 400, |
||||
data: { |
||||
message: 'ERROR MESSAGE', |
||||
}, |
||||
}; |
||||
|
||||
expect(reduceError(error)).toMatchObject({ |
||||
data: { |
||||
message: 'ERROR MESSAGE', |
||||
}, |
||||
}); |
||||
}); |
||||
|
||||
it('should return original error for errors other than FetchError (not data property)', () => { |
||||
const error = { |
||||
message: 'ERROR MESSAGE', |
||||
}; |
||||
|
||||
expect(reduceError(error)).toMatchObject({ |
||||
message: 'ERROR MESSAGE', |
||||
}); |
||||
}); |
||||
}); |
@ -0,0 +1,21 @@ |
||||
import _ from 'lodash'; |
||||
|
||||
/** |
||||
* Graphite-web before v1.6 returns HTTP 500 with full stack traces in an HTML page |
||||
* when a query fails. It results in massive error alerts with HTML tags in the UI. |
||||
* This function removes all HTML tags and keeps only the last line from the stack |
||||
* trace which should be the most meaningful. |
||||
*/ |
||||
export function reduceError(error: any): any { |
||||
if (error && error.status === 500 && error.data?.message?.startsWith('<body')) { |
||||
// Remove all HTML tags and take the last line from the stack trace
|
||||
const newMessage = _.last<string>( |
||||
error.data.message |
||||
.replace(/(<([^>]+)>)/gi, '') |
||||
.trim() |
||||
.split(/\n/) |
||||
)!.replace(/u?&#[^;]+;/g, ''); |
||||
error.data.message = `Graphite encountered an unexpected error while handling your request. ${newMessage}`; |
||||
} |
||||
return error; |
||||
} |
Loading…
Reference in new issue