mirror of https://github.com/zulip/zulip.git
sentry: Address Sentry JavaScript 7.x deprecations.
https://docs.sentry.io/platforms/javascript/migration/v7-to-v8/ Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
e9b031c003
commit
a8304fb324
|
@ -93,7 +93,7 @@ export function error(msg: string, more_info?: object, original_error?: unknown)
|
||||||
// Note that original_error could be of any type, because you can "raise"
|
// Note that original_error could be of any type, because you can "raise"
|
||||||
// any type -- something we do see in practice with the error
|
// any type -- something we do see in practice with the error
|
||||||
// object being "dead": https://github.com/zulip/zulip/issues/18374
|
// object being "dead": https://github.com/zulip/zulip/issues/18374
|
||||||
Sentry.getCurrentHub().captureException(new Error(msg, {cause: original_error}));
|
Sentry.captureException(new Error(msg, {cause: original_error}));
|
||||||
|
|
||||||
const args = build_arg_list(msg, more_info);
|
const args = build_arg_list(msg, more_info);
|
||||||
logger.error(...args);
|
logger.error(...args);
|
||||||
|
|
|
@ -48,28 +48,32 @@ function call(args: AjaxRequestHandlerOptions): JQuery.jqXHR<unknown> | undefine
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const existing_span = Sentry.getCurrentHub().getScope().getSpan();
|
|
||||||
const txn_title = `call ${args.type} ${normalize_path(args.url)}`;
|
const txn_title = `call ${args.type} ${normalize_path(args.url)}`;
|
||||||
const span_data = {
|
const span_data = {
|
||||||
op: "function",
|
op: "function",
|
||||||
description: txn_title,
|
|
||||||
data: {
|
data: {
|
||||||
url: args.url,
|
url: args.url,
|
||||||
method: args.type,
|
method: args.type,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let span: Sentry.Span | undefined;
|
/* istanbul ignore if */
|
||||||
if (!shouldCreateSpanForRequest(args.url)) {
|
if (!shouldCreateSpanForRequest(args.url)) {
|
||||||
// Leave the span unset, so we don't record a transaction
|
return call_in_span(undefined, args);
|
||||||
} else {
|
|
||||||
if (!existing_span) {
|
|
||||||
span = Sentry.startTransaction({...span_data, name: txn_title});
|
|
||||||
} else {
|
|
||||||
/* istanbul ignore next */
|
|
||||||
span = existing_span.startChild(span_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return Sentry.startSpanManual({...span_data, name: txn_title}, (span) => {
|
||||||
|
try {
|
||||||
|
return call_in_span(span, args);
|
||||||
|
} catch (error) /* istanbul ignore next */ {
|
||||||
|
span?.end();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function call_in_span(
|
||||||
|
span: Sentry.Span | undefined,
|
||||||
|
args: AjaxRequestHandlerOptions,
|
||||||
|
): JQuery.jqXHR<unknown> {
|
||||||
// Remember the number of completed password changes when the
|
// Remember the number of completed password changes when the
|
||||||
// request was initiated. This allows us to detect race
|
// request was initiated. This allows us to detect race
|
||||||
// situations where a password change occurred before we got a
|
// situations where a password change occurred before we got a
|
||||||
|
@ -84,9 +88,10 @@ function call(args: AjaxRequestHandlerOptions): JQuery.jqXHR<unknown> | undefine
|
||||||
// Ignore errors by default
|
// Ignore errors by default
|
||||||
});
|
});
|
||||||
args.error = function wrapped_error(xhr, error_type, xhn) {
|
args.error = function wrapped_error(xhr, error_type, xhn) {
|
||||||
|
/* istanbul ignore if */
|
||||||
if (span !== undefined) {
|
if (span !== undefined) {
|
||||||
span.setHttpStatus(xhr.status);
|
Sentry.setHttpStatus(span, xhr.status);
|
||||||
span.finish();
|
span.end();
|
||||||
}
|
}
|
||||||
if (reload_state.is_in_progress()) {
|
if (reload_state.is_in_progress()) {
|
||||||
// If we're in the process of reloading the browser,
|
// If we're in the process of reloading the browser,
|
||||||
|
@ -149,9 +154,10 @@ function call(args: AjaxRequestHandlerOptions): JQuery.jqXHR<unknown> | undefine
|
||||||
// Do nothing by default
|
// Do nothing by default
|
||||||
});
|
});
|
||||||
args.success = function wrapped_success(data, textStatus, jqXHR) {
|
args.success = function wrapped_success(data, textStatus, jqXHR) {
|
||||||
|
/* istanbul ignore if */
|
||||||
if (span !== undefined) {
|
if (span !== undefined) {
|
||||||
span.setHttpStatus(jqXHR.status);
|
Sentry.setHttpStatus(span, jqXHR.status);
|
||||||
span.finish();
|
span.end();
|
||||||
}
|
}
|
||||||
if (reload_state.is_in_progress()) {
|
if (reload_state.is_in_progress()) {
|
||||||
// If we're in the process of reloading the browser,
|
// If we're in the process of reloading the browser,
|
||||||
|
@ -165,15 +171,7 @@ function call(args: AjaxRequestHandlerOptions): JQuery.jqXHR<unknown> | undefine
|
||||||
orig_success(data, textStatus, jqXHR);
|
orig_success(data, textStatus, jqXHR);
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
return $.ajax(args);
|
||||||
const scope = Sentry.getCurrentHub().pushScope();
|
|
||||||
if (span !== undefined) {
|
|
||||||
scope.setSpan(span);
|
|
||||||
}
|
|
||||||
return $.ajax(args);
|
|
||||||
} finally {
|
|
||||||
Sentry.getCurrentHub().popScope();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function get(options: AjaxRequestHandlerOptions): JQuery.jqXHR<unknown> | undefined {
|
export function get(options: AjaxRequestHandlerOptions): JQuery.jqXHR<unknown> | undefined {
|
||||||
|
|
|
@ -446,23 +446,11 @@ export function show(raw_terms: NarrowTerm[], show_opts: ShowMessageViewOpts): v
|
||||||
...show_opts,
|
...show_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
const existing_span = Sentry.getCurrentHub().getScope().getSpan();
|
|
||||||
const span_data = {
|
const span_data = {
|
||||||
op: "function",
|
op: "function",
|
||||||
description: "narrow",
|
|
||||||
data: {raw_terms, trigger: opts.trigger},
|
data: {raw_terms, trigger: opts.trigger},
|
||||||
};
|
};
|
||||||
let span;
|
void Sentry.startSpan({...span_data, name: "narrow"}, async (span) => {
|
||||||
if (!existing_span) {
|
|
||||||
span = Sentry.startTransaction({...span_data, name: "narrow"});
|
|
||||||
} else {
|
|
||||||
span = existing_span.startChild(span_data);
|
|
||||||
}
|
|
||||||
let do_close_span = true;
|
|
||||||
try {
|
|
||||||
const scope = Sentry.getCurrentHub().pushScope();
|
|
||||||
scope.setSpan(span);
|
|
||||||
|
|
||||||
const id_info: TargetMessageIdInfo = {
|
const id_info: TargetMessageIdInfo = {
|
||||||
target_id: undefined,
|
target_id: undefined,
|
||||||
local_select_id: undefined,
|
local_select_id: undefined,
|
||||||
|
@ -779,26 +767,16 @@ export function show(raw_terms: NarrowTerm[], show_opts: ShowMessageViewOpts): v
|
||||||
then_select_offset,
|
then_select_offset,
|
||||||
);
|
);
|
||||||
|
|
||||||
const post_span = span.startChild({
|
const post_span_context = {
|
||||||
|
name: "post-narrow busy time",
|
||||||
op: "function",
|
op: "function",
|
||||||
description: "post-narrow busy time",
|
};
|
||||||
});
|
await Sentry.startSpan(post_span_context, async () => {
|
||||||
do_close_span = false;
|
span?.setStatus("ok");
|
||||||
span.setStatus("ok");
|
await new Promise((resolve) => setTimeout(resolve, 0));
|
||||||
setTimeout(() => {
|
|
||||||
resize.resize_stream_filters_container();
|
resize.resize_stream_filters_container();
|
||||||
post_span.finish();
|
});
|
||||||
span.finish();
|
});
|
||||||
}, 0);
|
|
||||||
} catch (error) {
|
|
||||||
span.setStatus("unknown_error");
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
if (do_close_span) {
|
|
||||||
span.finish();
|
|
||||||
}
|
|
||||||
Sentry.getCurrentHub().popScope();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function navigate_to_anchor_message(opts: {
|
function navigate_to_anchor_message(opts: {
|
||||||
|
|
|
@ -19,7 +19,7 @@ export class MessageState {
|
||||||
server_acked = false;
|
server_acked = false;
|
||||||
saw_event = false;
|
saw_event = false;
|
||||||
|
|
||||||
txn: Sentry.Transaction | undefined = undefined;
|
span: Sentry.Span | undefined = undefined;
|
||||||
event_span: Sentry.Span | undefined = undefined;
|
event_span: Sentry.Span | undefined = undefined;
|
||||||
|
|
||||||
constructor(opts: {local_id: string; locally_echoed: boolean}) {
|
constructor(opts: {local_id: string; locally_echoed: boolean}) {
|
||||||
|
@ -27,17 +27,27 @@ export class MessageState {
|
||||||
this.locally_echoed = opts.locally_echoed;
|
this.locally_echoed = opts.locally_echoed;
|
||||||
}
|
}
|
||||||
|
|
||||||
start_send(): Sentry.Transaction {
|
wrap_send(callback: () => void): void {
|
||||||
this.txn = Sentry.startTransaction({
|
Sentry.startSpanManual(
|
||||||
op: "function",
|
{
|
||||||
description: "message send",
|
op: "function",
|
||||||
name: "message send",
|
name: "message send",
|
||||||
});
|
},
|
||||||
this.event_span = this.txn.startChild({
|
(span) => {
|
||||||
op: "function",
|
try {
|
||||||
description: "message send (server event loop)",
|
this.span = span;
|
||||||
});
|
this.event_span = Sentry.startInactiveSpan({
|
||||||
return this.txn;
|
op: "function",
|
||||||
|
name: "message send (server event loop)",
|
||||||
|
});
|
||||||
|
callback();
|
||||||
|
} catch (error) {
|
||||||
|
this.event_span?.end();
|
||||||
|
span?.end();
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
mark_disparity(): void {
|
mark_disparity(): void {
|
||||||
|
@ -54,22 +64,27 @@ export class MessageState {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.saw_event = true;
|
this.saw_event = true;
|
||||||
this.event_span.finish();
|
this.event_span?.end();
|
||||||
this.maybe_finish_txn();
|
this.maybe_finish_txn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
report_error(): void {
|
||||||
|
this.event_span?.end();
|
||||||
|
this.span?.end();
|
||||||
|
}
|
||||||
|
|
||||||
maybe_finish_txn(): void {
|
maybe_finish_txn(): void {
|
||||||
if (!this.saw_event || !this.server_acked) {
|
if (!this.saw_event || !this.server_acked) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const setTag = (name: string, val: boolean): void => {
|
const setTag = (name: string, val: boolean): void => {
|
||||||
const str_val = val ? "true" : "false";
|
const str_val = val ? "true" : "false";
|
||||||
this.event_span!.setTag(name, str_val);
|
this.event_span?.setAttribute(name, str_val);
|
||||||
this.txn!.setTag(name, str_val);
|
this.span?.setAttribute(name, str_val);
|
||||||
};
|
};
|
||||||
setTag("rendered_changed", this.rendered_changed);
|
setTag("rendered_changed", this.rendered_changed);
|
||||||
setTag("locally_echoed", this.locally_echoed);
|
setTag("locally_echoed", this.locally_echoed);
|
||||||
this.txn!.finish();
|
this.span?.end();
|
||||||
messages.delete(this.local_id);
|
messages.delete(this.local_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,13 +117,13 @@ export function get_message_state(local_id: string): MessageState | undefined {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function start_send(local_id: string): Sentry.Transaction | undefined {
|
export function wrap_send(local_id: string, callback: () => void): void {
|
||||||
const state = get_message_state(local_id);
|
const state = get_message_state(local_id);
|
||||||
if (!state) {
|
if (state) {
|
||||||
return undefined;
|
state.wrap_send(callback);
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
return state.start_send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mark_disparity(local_id: string): void {
|
export function mark_disparity(local_id: string): void {
|
||||||
|
|
|
@ -61,9 +61,9 @@ if (sentry_params !== undefined) {
|
||||||
|
|
||||||
release: "zulip-server@" + ZULIP_VERSION,
|
release: "zulip-server@" + ZULIP_VERSION,
|
||||||
integrations: [
|
integrations: [
|
||||||
new Sentry.BrowserTracing({
|
Sentry.browserTracingIntegration({
|
||||||
startTransactionOnLocationChange: false,
|
instrumentNavigation: false,
|
||||||
beforeNavigate(context) {
|
beforeStartSpan(context) {
|
||||||
return {
|
return {
|
||||||
...context,
|
...context,
|
||||||
metadata: {source: "custom"},
|
metadata: {source: "custom"},
|
||||||
|
@ -101,8 +101,5 @@ if (sentry_params !== undefined) {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Always add the tracing extensions, so Sentry doesn't throw runtime errors if one calls
|
|
||||||
// startTransaction without having created the Sentry.BrowserTracing object.
|
|
||||||
Sentry.addTracingExtensions();
|
|
||||||
Sentry.init({});
|
Sentry.init({});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import * as Sentry from "@sentry/browser";
|
|
||||||
|
|
||||||
import * as blueslip from "./blueslip";
|
import * as blueslip from "./blueslip";
|
||||||
import * as channel from "./channel";
|
import * as channel from "./channel";
|
||||||
import * as people from "./people";
|
import * as people from "./people";
|
||||||
|
@ -17,10 +15,7 @@ export function send_message(request, on_success, error) {
|
||||||
locally_echoed: request.locally_echoed,
|
locally_echoed: request.locally_echoed,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const txn = sent_messages.start_send(request.local_id);
|
sent_messages.wrap_send(request.local_id, () => {
|
||||||
try {
|
|
||||||
const scope = Sentry.getCurrentHub().pushScope();
|
|
||||||
scope.setSpan(txn);
|
|
||||||
channel.post({
|
channel.post({
|
||||||
url: "/json/messages",
|
url: "/json/messages",
|
||||||
data: request,
|
data: request,
|
||||||
|
@ -58,6 +53,7 @@ export function send_message(request, on_success, error) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error(xhr, error_type) {
|
error(xhr, error_type) {
|
||||||
|
sent_messages.get_message_state(request.local_id)?.report_error();
|
||||||
if (error_type !== "timeout" && reload_state.is_pending()) {
|
if (error_type !== "timeout" && reload_state.is_pending()) {
|
||||||
// The error might be due to the server changing
|
// The error might be due to the server changing
|
||||||
reload.initiate({
|
reload.initiate({
|
||||||
|
@ -72,9 +68,7 @@ export function send_message(request, on_success, error) {
|
||||||
error(response, xhr.responseJSON?.code);
|
error(response, xhr.responseJSON?.code);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} finally {
|
});
|
||||||
Sentry.getCurrentHub().popScope();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function reply_message(opts) {
|
export function reply_message(opts) {
|
||||||
|
|
|
@ -14,9 +14,12 @@ const sent_messages = mock_esm("../src/sent_messages", {
|
||||||
start_tracking_message: noop,
|
start_tracking_message: noop,
|
||||||
get_message_state: () => ({
|
get_message_state: () => ({
|
||||||
report_server_ack: noop,
|
report_server_ack: noop,
|
||||||
|
report_error: noop,
|
||||||
saw_event: true,
|
saw_event: true,
|
||||||
}),
|
}),
|
||||||
start_send: noop,
|
wrap_send(_local_id, callback) {
|
||||||
|
callback();
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const server_events = mock_esm("../src/server_events");
|
const server_events = mock_esm("../src/server_events");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue