mirror of https://github.com/zulip/zulip.git
sentry: Annotate all channel calls.
This commit is contained in:
parent
c67cd5adb4
commit
9d6ca32c59
|
@ -1,9 +1,11 @@
|
|||
import * as Sentry from "@sentry/browser";
|
||||
import $ from "jquery";
|
||||
import _ from "lodash";
|
||||
|
||||
import * as blueslip from "./blueslip";
|
||||
import {page_params} from "./page_params";
|
||||
import * as reload_state from "./reload_state";
|
||||
import {normalize_path} from "./sentry";
|
||||
import * as spectators from "./spectators";
|
||||
|
||||
let password_change_in_progress = false;
|
||||
|
@ -24,6 +26,28 @@ function call(args) {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const existing_span = Sentry.getCurrentHub().getScope().getSpan();
|
||||
const txn_title = `call ${args.type} ${normalize_path(args.url)}`;
|
||||
const span_data = {
|
||||
op: "function",
|
||||
description: txn_title,
|
||||
data: {
|
||||
url: args.url,
|
||||
method: args.type,
|
||||
},
|
||||
};
|
||||
let span;
|
||||
if (args.type === "GET" && args.url === "/json/events") {
|
||||
// Leave the span unset, so we don't record a transaction
|
||||
} else {
|
||||
if (!existing_span) {
|
||||
span = Sentry.startTransaction({...span_data, name: txn_title});
|
||||
} else {
|
||||
/* istanbul ignore next */
|
||||
span = existing_span.startChild(span_data);
|
||||
}
|
||||
}
|
||||
|
||||
// Remember the number of completed password changes when the
|
||||
// request was initiated. This allows us to detect race
|
||||
// situations where a password change occurred before we got a
|
||||
|
@ -37,6 +61,10 @@ function call(args) {
|
|||
orig_error = function () {};
|
||||
}
|
||||
args.error = function wrapped_error(xhr, error_type, xhn) {
|
||||
if (span !== undefined) {
|
||||
span.setHttpStatus(xhr.status);
|
||||
span.finish();
|
||||
}
|
||||
if (reload_state.is_in_progress()) {
|
||||
// If we're in the process of reloading the browser,
|
||||
// there's no point in running the error handler,
|
||||
|
@ -74,6 +102,7 @@ function call(args) {
|
|||
// the login page conveys the same information with a
|
||||
// smoother relogin experience.
|
||||
window.location.replace(page_params.login_page);
|
||||
return;
|
||||
}
|
||||
} else if (xhr.status === 403) {
|
||||
try {
|
||||
|
@ -98,6 +127,10 @@ function call(args) {
|
|||
orig_success = function () {};
|
||||
}
|
||||
args.success = function wrapped_success(data, textStatus, jqXHR) {
|
||||
if (span !== undefined) {
|
||||
span.setHttpStatus(jqXHR.status);
|
||||
span.finish();
|
||||
}
|
||||
if (reload_state.is_in_progress()) {
|
||||
// If we're in the process of reloading the browser,
|
||||
// there's no point in running the success handler,
|
||||
|
@ -110,7 +143,15 @@ function call(args) {
|
|||
orig_success(data, textStatus, jqXHR);
|
||||
};
|
||||
|
||||
try {
|
||||
const scope = Sentry.getCurrentHub().pushScope();
|
||||
if (span !== undefined) {
|
||||
scope.setSpan(span);
|
||||
}
|
||||
return $.ajax(args);
|
||||
} finally {
|
||||
Sentry.getCurrentHub().popScope();
|
||||
}
|
||||
}
|
||||
|
||||
export function get(options) {
|
||||
|
|
|
@ -10,6 +10,9 @@ type UserInfo = {
|
|||
};
|
||||
|
||||
export function normalize_path(path: string, is_portico = false): string {
|
||||
if (path === undefined) {
|
||||
return "unknown";
|
||||
}
|
||||
path = path
|
||||
.replace(/\/\d+(\/|$)/, "/*$1")
|
||||
.replace(
|
||||
|
|
|
@ -378,3 +378,48 @@ test("while_reloading", () => {
|
|||
},
|
||||
});
|
||||
});
|
||||
|
||||
test("error in callback", () => {
|
||||
let success_called = false;
|
||||
let error_called = false;
|
||||
let raised_error = false;
|
||||
test_with_mock_ajax({
|
||||
run_code() {
|
||||
channel.get({
|
||||
url: "/json/endpoint",
|
||||
success() {
|
||||
success_called = true;
|
||||
throw new Error("success");
|
||||
},
|
||||
error() {
|
||||
error_called = true;
|
||||
throw new Error("failure");
|
||||
},
|
||||
});
|
||||
},
|
||||
check_ajax_options(options) {
|
||||
try {
|
||||
options.simulate_success();
|
||||
} catch (error) {
|
||||
assert.equal(error.message, "success");
|
||||
raised_error = true;
|
||||
}
|
||||
assert.ok(success_called);
|
||||
assert.ok(raised_error);
|
||||
assert.ok(!error_called);
|
||||
|
||||
success_called = false;
|
||||
raised_error = false;
|
||||
|
||||
try {
|
||||
options.simulate_error();
|
||||
} catch (error) {
|
||||
assert.equal(error.message, "failure");
|
||||
raised_error = true;
|
||||
}
|
||||
assert.ok(!success_called);
|
||||
assert.ok(raised_error);
|
||||
assert.ok(error_called);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue