Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: send errors to sentry #60

Merged
merged 5 commits into from
Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ SERVICE_PUSHER_BEAMS_INSTANCE_ID=
SERVICE_PUSHER_BEAMS_SECRET_KEY=
HUB_URL=
SNAPSHOT_URI=
SENTRY_DSN=
SENTRY_TRACE_SAMPLE_RATE=
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"prettier": "@snapshot-labs/prettier-config",
"dependencies": {
"@pusher/push-notifications-server": "^1.2.5",
"@sentry/node": "^7.57.0",
"@snapshot-labs/snapshot.js": "^0.3.68",
"bluebird": "^3.7.2",
"body-parser": "^1.19.0",
Expand Down
2 changes: 2 additions & 0 deletions src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import express from 'express';
import { sendEvent } from './events';
import pkg from '../package.json';
import { last_mci } from './replay';
import { capture } from './helpers/sentry';

const router = express.Router();

Expand All @@ -26,6 +27,7 @@ router.get('/test', async (req, res) => {
await sendEvent(event, url);
return res.json({ url, success: true });
} catch (e) {
capture(e);
return res.json({ url, error: e });
}
});
Expand Down
16 changes: 9 additions & 7 deletions src/discord.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import removeMd from 'remove-markdown';
import { shortenAddress } from './helpers/utils';
import { subs, loadSubscriptions } from './subscriptions';
import { getSpace, getProposal } from './helpers/proposal';
import { capture } from './helpers/sentry';

const CLIENT_ID = process.env.DISCORD_CLIENT_ID || '';
const token = process.env.DISCORD_TOKEN || '';
Expand Down Expand Up @@ -96,7 +97,7 @@ const rest = new REST({ version: '10' }).setToken(token);
await rest.put(Routes.applicationCommands(CLIENT_ID), { body: commands });
console.log('Successfully reloaded application (/) commands.');
} catch (error) {
console.error(error);
capture(error);
}
})();

Expand All @@ -107,7 +108,7 @@ export const setActivity = (message, url?) => {
client.user.setActivity(message, { type: 'WATCHING', url });
return true;
} catch (e) {
console.log('Missing activity', e);
capture(e);
}
};

Expand All @@ -121,6 +122,7 @@ const checkPermissions = async (channelId, botId) => {
return `I do not have permission to send messages in this channel ${discordChannel.toString()}, Add permission and try again`;
return true;
} catch (error) {
capture(error);
console.log('Error checking permissions', error);
const channelExistWithName = client.channels.cache.find(c => c.name === channelId);
if (channelExistWithName) {
Expand Down Expand Up @@ -192,7 +194,7 @@ async function snapshotHelpCommandHandler(interaction) {
Have any questions? Join our discord: https://discord.snapshot.org`
}
);
interaction.reply({ embeds: [embed], ephemeral: true }).catch(console.error);
interaction.reply({ embeds: [embed], ephemeral: true }).catch(capture);
}

async function snapshotCommandHandler(interaction, commandType) {
Expand All @@ -212,7 +214,7 @@ async function snapshotCommandHandler(interaction, commandType) {
);
if (commandType === 'add') {
const permissions = await checkPermissions(channelId, CLIENT_ID);
if (permissions !== true) return interaction.reply(permissions).catch(console.error);
if (permissions !== true) return interaction.reply(permissions).catch(capture);

const space = await getSpace(spaceId);
if (!space) return interaction.reply(`Space not found: ${inlineCode(spaceId)}`);
Expand All @@ -233,7 +235,7 @@ async function snapshotCommandHandler(interaction, commandType) {
{ name: 'Mention', value: mention || 'None', inline: true }
)
.setDescription('You have successfully subscribed to space events.');
interaction.reply({ embeds: [embed], ephemeral: true }).catch(console.error);
interaction.reply({ embeds: [embed], ephemeral: true }).catch(capture);
} else if (commandType === 'remove') {
const query = `DELETE FROM subscriptions WHERE guild = ? AND channel = ? AND space = ?`;
await db.queryAsync(query, [interaction.guildId, channelId, spaceId]);
Expand All @@ -246,7 +248,7 @@ async function snapshotCommandHandler(interaction, commandType) {
{ name: 'Channel', value: `<#${channelId}>`, inline: true }
)
.setDescription('You have successfully unsubscribed to space events.');
interaction.reply({ embeds: [embed], ephemeral: true }).catch(console.error);
interaction.reply({ embeds: [embed], ephemeral: true }).catch(capture);
}
}

Expand Down Expand Up @@ -275,7 +277,7 @@ export const sendMessage = async (channel, message) => {
await speaker.send(message);
return true;
} catch (e) {
console.log('Discord error:', e);
capture(e);
}
};

Expand Down
4 changes: 4 additions & 0 deletions src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { sendPushNotification } from './helpers/beams';
import db from './helpers/mysql';
import { sha256 } from './helpers/utils';
import { getProposal, getProposalScores } from './helpers/proposal';
import { capture } from './helpers/sentry';

const delay = 5;
const interval = 15;
Expand Down Expand Up @@ -110,6 +111,7 @@ async function processEvents(subscribers) {
const scores = await getProposalScores(proposalId);
console.log('[events] Stored scores on proposal/end', proposalId, scores);
} catch (e) {
capture(e);
console.log('[events] getProposalScores failed:', e);
}
}
Expand All @@ -127,6 +129,7 @@ async function processEvents(subscribers) {
]);
console.log(`[events] Event sent ${event.id} ${event.event}`);
} catch (e) {
capture(e);
console.log('[events]', e);
}
}
Expand All @@ -138,6 +141,7 @@ async function run() {
console.log('[events] Subscribers', subscribers.length);
await processEvents(subscribers);
} catch (e) {
capture(e);
console.log('[events] Failed to process', e);
}
await snapshot.utils.sleep(interval * 1e3);
Expand Down
5 changes: 3 additions & 2 deletions src/helpers/beams.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import PushNotifications from '@pusher/push-notifications-server';
import snapshot from '@snapshot-labs/snapshot.js';
import chunk from 'lodash.chunk';
import { getProposal } from './proposal';
import { capture } from './sentry';

const beams = new PushNotifications({
instanceId: process.env.SERVICE_PUSHER_BEAMS_INSTANCE_ID ?? '',
Expand All @@ -22,7 +23,7 @@ async function getSubscribers(space) {
const result = await snapshot.utils.subgraphRequest('https://hub.snapshot.org/graphql', query);
subscriptions = result.subscriptions || [];
} catch (error) {
console.log('[events] Snapshot hub error:', error);
capture(error);
}
return subscriptions.map(subscription => subscription.address);
}
Expand All @@ -48,6 +49,6 @@ export const sendPushNotification = async event => {
});
}
} catch (e) {
console.log('[events] Error sending push notification', e);
capture(e);
}
};
41 changes: 41 additions & 0 deletions src/helpers/sentry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as Sentry from '@sentry/node';
import { Express } from 'express';

export function initLogger(app: Express) {
if (process.env.NODE_ENV !== 'production') {
return;
}

Sentry.init({
dsn: process.env.SENTRY_DSN,
integrations: [
new Sentry.Integrations.Http({ tracing: true }),
new Sentry.Integrations.Express({ app }),
...Sentry.autoDiscoverNodePerformanceMonitoringIntegrations()
],

tracesSampleRate: parseFloat(process.env.SENTRY_TRACE_SAMPLE_RATE as string)
});

app.use(Sentry.Handlers.requestHandler());
app.use(Sentry.Handlers.tracingHandler());
}

export function fallbackLogger(app: Express) {
if (process.env.NODE_ENV !== 'production') return;

app.use(Sentry.Handlers.errorHandler());
wa0x6e marked this conversation as resolved.
Show resolved Hide resolved
// eslint-disable-next-line @typescript-eslint/no-unused-vars
app.use(function onError(err: any, req: any, res: any, _: any) {
res.statusCode = 500;
res.end(`${res.sentry}\n`);
});
}

export function capture(e: any) {
if (process.env.NODE_ENV !== 'production') {
return console.error(e);
}

Sentry.captureException(e);
wa0x6e marked this conversation as resolved.
Show resolved Hide resolved
}
5 changes: 5 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@ import 'dotenv/config';
import express from 'express';
import bodyParser from 'body-parser';
import cors from 'cors';
import { initLogger, fallbackLogger } from './helpers/sentry';
import api from './api';
import './replay';
import './discord';

const app = express();
const PORT = process.env.PORT || 3000;

initLogger(app);

app.use(bodyParser.json({ limit: '8mb' }));
app.use(bodyParser.urlencoded({ limit: '8mb', extended: false }));
app.use(cors({ maxAge: 86400 }));

app.use('/api', api);

fallbackLogger(app);

app.listen(PORT, () => console.log(`Listening at http://localhost:${PORT}`));
6 changes: 4 additions & 2 deletions src/replay.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import snapshot from '@snapshot-labs/snapshot.js';
import { EnumType } from 'json-to-graphql-query';
import db from './helpers/mysql';
import { capture } from './helpers/sentry';
import { handleCreatedEvent, handleDeletedEvent } from './events';

const hubURL = process.env.HUB_URL || 'https://hub.snapshot.org';
Expand Down Expand Up @@ -39,6 +40,7 @@ async function getNextMessages(mci: number) {
const results = await snapshot.utils.subgraphRequest(`${hubURL}/graphql`, query);
return results.messages;
} catch (e) {
capture(e);
console.log('Failed to load messages', e);
return;
}
Expand Down Expand Up @@ -67,7 +69,7 @@ async function processMessages(messages: any[]) {
}
lastMessageMci = message.mci;
} catch (error) {
console.log('[replay] Failed to process message', message.id, error);
capture(error);
break;
}
}
Expand All @@ -76,7 +78,7 @@ async function processMessages(messages: any[]) {
await updateLastMci(lastMessageMci);
console.log('[replay] Updated to MCI', lastMessageMci);
}
return
return;
}

async function run() {
Expand Down
Loading