Skip to content
Snippets Groups Projects
Commit 67d3ff4b authored by Tom Robinson's avatar Tom Robinson
Browse files

Server/timeout error screens + admin email setting

parent be5b9316
No related branches found
No related tags found
No related merge requests found
......@@ -409,6 +409,7 @@ CardControllers.controller('CardDetail', [
renderAll();
let startTime = new Date();
// make our api call
Metabase.dataset(dataset_query, function (result) {
queryResult = result;
......@@ -484,7 +485,7 @@ CardControllers.controller('CardDetail', [
}, function (error) {
isRunning = false;
queryResult = { error: error };
queryResult = { error: error, duration: new Date() - startTime };
renderAll();
});
......
......@@ -254,10 +254,45 @@
background-image: url('/app/img/no_understand.svg');
}
.QueryError-image--serverError {
width: 120px;
height: 120px;
background-image: url('/app/img/stopwatch.svg');
}
.QueryError-image--timeout {
width: 120px;
height: 120px;
background-image: url('/app/img/stopwatch.svg');
}
.QueryError-messageText {
line-height: 1.4;
}
.QueryError-adminEmail {
position: relative;
display: inline-block;
border-radius: var(--default-border-radius);
border: 1px solid rgb(197, 197, 197);
margin-top: var(--margin-2);
padding: var(--padding-1) var(--padding-4) var(--padding-1) var(--padding-4);
}
.QueryError-adminEmail:before {
content: "Admin Email";
font-size: 10px;
text-align: center;
text-transform: uppercase;
background-color: white;
padding-left: var(--padding-1);
padding-right: var(--padding-1);
position: absolute;
top: -0.75em;
left: 50%;
margin-left: -41px; /* ugh */
}
/* GUI BUILDER */
......
......@@ -19,6 +19,9 @@ const MetabaseSettings = {
},
// these are all special accessors which provide a lookup of a property plus some additional help
adminEmail: function() {
return mb_settings.admin_email;
},
isEmailConfigured: function() {
return mb_settings.email_configured;
......
......@@ -8,6 +8,7 @@ import QueryVisualizationObjectDetailTable from './QueryVisualizationObjectDetai
import RunButton from './RunButton.jsx';
import VisualizationSettings from './VisualizationSettings.jsx';
import MetabaseSettings from "metabase/lib/settings";
import Query from "metabase/lib/query";
import cx from "classnames";
......@@ -167,23 +168,39 @@ export default class QueryVisualization extends Component {
</div>
);
} else {
let error = this.props.result.error;
let { result } = this.props;
let error = result.error;
if (error) {
let message;
// transform HTTP errors to plain text error messages, and always show them
if (typeof error.status === "number") {
if (error.status === 503) {
error = "I'm sorry, the server timed out while asking your question.";
let adminEmail = MetabaseSettings.adminEmail();
// Assume if the request took more than 15 seconds it was due to a timeout
// Some platforms like Heroku return a 503 for numerous types of errors so we can't use the status code to distinguish between timeouts and other failures.
if (result.duration > 15*1000) {
viz = (
<div className="QueryError flex full align-center">
<div className="QueryError-image QueryError-image--serverError"></div>
<div className="QueryError-message text-centered">
<h1 className="text-bold">Your question took too long</h1>
<p className="QueryError-messageText">We didn't get an answer back from your database in time, so we had to stop. You can try again in a minute, or if the problem persists, you can email an admin to let them know.</p>
{adminEmail && <span className="QueryError-adminEmail"><a className="no-decoration" href={"mailto:"+adminEmail}>{adminEmail}</a></span>}
</div>
</div>
);
} else {
error = "I'm sorry, an error occured: " + error.statusText;
viz = (
<div className="QueryError flex full align-center">
<div className="QueryError-image QueryError-image--timeout"></div>
<div className="QueryError-message text-centered">
<h1 className="text-bold">We're experiencing server issues</h1>
<p className="QueryError-messageText">Try refreshing the page after waiting a minute or two. If the problem persists we'd recommend you contact an admin.</p>
{adminEmail && <span className="QueryError-adminEmail"><a className="no-decoration" href={"mailto:"+adminEmail}>{adminEmail}</a></span>}
</div>
</div>
);
}
message = error;
}
// always show errors for native queries
if (this.props.card.dataset_query && this.props.card.dataset_query.type === 'native') {
message = error;
}
if (message) {
} else if (this.props.card.dataset_query && this.props.card.dataset_query.type === 'native') {
// always show errors for native queries
viz = (
<div className="QueryError flex full align-center text-error">
<div className="QueryError-iconWrapper">
......@@ -194,7 +211,6 @@ export default class QueryVisualization extends Component {
<span className="QueryError-message">{message}</span>
</div>
);
} else {
viz = (
<div className="QueryError flex full align-center">
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="108px" height="118px" viewBox="0 0 108 118" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<circle stroke="#E3E3E3" stroke-width="3" fill="#FFFFFF" cx="53" cy="65" r="52"></circle>
<path d="M54.9857911,57.2483919 C54.9951751,57.1698571 55,57.0899169 55,57.008845 L55,38.991155 C55,37.8896739 54.1045695,37 53,37 C51.8877296,37 51,37.8914705 51,38.991155 L51,57.008845 C51,57.0899255 51.0048519,57.1698584 51.0142819,57.2483732 C47.5565832,58.1314817 45,61.2671799 45,65 C45,69.418278 48.581722,73 53,73 C57.418278,73 61,69.418278 61,65 C61,61.2672062 58.4434528,58.1315259 54.9857911,57.2483919 Z" fill="#E3E3E3"></path>
<rect stroke="#E3E3E3" stroke-width="3" fill="#F8F8F8" x="45" y="1" width="16" height="15" rx="6"></rect>
<path d="M52,101 L54,101 L54,108 L52,108 L52,101 Z M52,22 L54,22 L54,29 L52,29 L52,22 Z M89,66 L89,64 L95.7338129,64 L95.7338129,66 L89,66 Z M9.52844494,66 L9.52844494,64 L16.2622579,64 L16.2622579,66 L9.52844494,66 Z M78.0473135,92.2999886 L79.4615271,90.8857751 L84.2230519,95.6472999 L82.8088383,97.0615134 L78.0473135,92.2999886 Z M22.0473135,34.2999886 L23.4615271,32.8857751 L28.2230519,37.6472999 L26.8088383,39.0615134 L22.0473135,34.2999886 Z M26.8088383,90.8857751 L28.2230519,92.2999886 L23.4615271,97.0615134 L22.0473135,95.6472999 L26.8088383,90.8857751 Z M82.8088383,32.8857751 L84.2230519,34.2999886 L79.4615271,39.0615134 L78.0473135,37.6472999 L82.8088383,32.8857751 Z" stroke="#E3E3E3" stroke-width="3" fill="#F8F8F8"></path>
<path d="M89,7 C91.2273181,4.42229162 94.9764573,4.42395737 97,7 L105,15 C107.579027,17.0283807 107.575629,20.7737606 105,23 L103,25 C100.772682,27.5777084 97.0235427,27.5760426 95,25 L87,17 C84.4209732,14.9716193 84.4243711,11.2262394 87,9 L89,7 L89,7 Z" stroke="#E3E3E3" stroke-width="3" fill="#F8F8F8"></path>
<rect stroke="#E3E3E3" stroke-width="3" fill="#F8F8F8" transform="translate(89.038462, 22.726619) rotate(-45.000000) translate(-89.038462, -22.726619) " x="84.8461538" y="17.676259" width="8.38461538" height="10.1007194"></rect>
<circle fill="#F8F8F8" cx="53" cy="65" r="5"></circle>
</g>
</svg>
......@@ -164,7 +164,8 @@
:anon_tracking_enabled (let [tracking? (get :anon-tracking-enabled)]
(or (nil? tracking?) (= "true" tracking?)))
:site_name (get :site-name)
:email_configured (not (s/blank? (get :email-smtp-host)))})
:email_configured (not (s/blank? (get :email-smtp-host)))
:admin_email (sel :one :field ['User :email] (k/where {:is_superuser true}))})
;; # IMPLEMENTATION
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment