Files
2024-02-15 17:01:50 +00:00

69 lines
1.9 KiB
TypeScript

import * as Sentry from '@sentry/react';
import {simpleMarkup} from 'sentry/views/starfish/utils/sqlish/formatters/simpleMarkup';
import {string} from 'sentry/views/starfish/utils/sqlish/formatters/string';
import {SQLishParser} from 'sentry/views/starfish/utils/sqlish/SQLishParser';
type StringFormatterOptions = Parameters<typeof string>[1];
enum Format {
STRING = 'string',
SIMPLE_MARKUP = 'simpleMarkup',
}
const FORMATTERS = {
[Format.STRING]: string,
[Format.SIMPLE_MARKUP]: simpleMarkup,
};
export class SQLishFormatter {
parser: SQLishParser;
constructor() {
this.parser = new SQLishParser();
}
toString(sql: string, options?: StringFormatterOptions) {
return this.toFormat(sql, Format.STRING, options);
}
toSimpleMarkup(sql: string) {
return this.toFormat(sql, Format.SIMPLE_MARKUP);
}
toFormat(sql: string, format: Format.STRING, options?: StringFormatterOptions): string;
toFormat(sql: string, format: Format.SIMPLE_MARKUP): React.ReactElement[];
toFormat(sql: string, format: Format, options?: StringFormatterOptions) {
let tokens;
const sentryTransaction = Sentry.getCurrentHub().getScope()?.getTransaction();
const sentrySpan = sentryTransaction?.startChild({
op: 'function',
description: 'SQLishFormatter.toFormat',
data: {
format,
},
});
try {
tokens = this.parser.parse(sql);
} catch (error) {
Sentry.withScope(scope => {
scope.setFingerprint(['sqlish-parse-error']);
// Get the last 100 characters of the error message
scope.setExtra('message', error.message?.slice(-100));
scope.setExtra('found', error.found);
Sentry.captureException(error);
});
// If we fail to parse the SQL, return the original string
return sql;
}
const formattedString = FORMATTERS[format](tokens, options);
sentrySpan?.finish();
return formattedString;
}
}