Skip to content

Commit ee22aa8

Browse files
authored
add sentry for error notifications via email (#2)
1 parent 3ac4886 commit ee22aa8

File tree

5 files changed

+142
-102
lines changed

5 files changed

+142
-102
lines changed

.hooks/pre-commit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env sh
22
. "$(dirname -- "$0")/_/hook.sh"
33

4-
deno fmt --check supabase/*
4+
deno fmt supabase/*
55
deno lint supabase/*

supabase/functions/.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
SENTRY_DSN=xxx
12
LASTFM_API_KEY=xxx
23
LASTFM_USERNAME=Insuit

supabase/functions/fetch-scrobbles/env.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
export const env = {
1+
export interface Variables {
2+
SUPABASE_URL: string;
3+
SUPABASE_ANON_KEY: string;
4+
LASTFM_API_KEY: string;
5+
LASTFM_USERNAME: string;
6+
}
7+
8+
export const env: Variables = {
29
SUPABASE_URL: Deno.env.get("SUPABASE_URL")!,
310
SUPABASE_ANON_KEY: Deno.env.get("SUPABASE_ANON_KEY")!,
411
LASTFM_API_KEY: Deno.env.get("LASTFM_API_KEY")!,
Lines changed: 27 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,33 @@
1-
import { createClient } from "https://esm.sh/@supabase/supabase-js@2";
2-
import { getRecentTracks } from "./lastfm.ts";
3-
import { Row, TableListened } from "./table.ts";
1+
import * as Sentry from "https://deno.land/x/sentry/index.mjs";
2+
import { scrobbles } from "./scrobbles.ts";
43
import { env } from "./env.ts";
54

6-
Deno.serve(async () => {
7-
const size = 50;
8-
const supabaseClient = createClient(env.SUPABASE_URL, env.SUPABASE_ANON_KEY);
9-
const table = new TableListened(supabaseClient);
10-
const startFrom: number | null = await table.getLastListenedDate();
11-
let totalPages = 1;
12-
let total = 0;
13-
let page = 1;
14-
15-
if (startFrom) {
16-
console.log(
17-
"Starting from last listened date:",
18-
new Date(startFrom * 1000).toLocaleString(),
19-
);
20-
} else {
21-
console.log("Database is empty, starting from the last page");
22-
}
5+
Sentry.init({
6+
dsn: Deno.env.get("SENTRY_DSN")!,
7+
defaultIntegrations: false,
8+
tracesSampleRate: 1.0,
9+
// deno-lint-ignore ban-ts-comment
10+
// @ts-ignore
11+
profilesSampleRate: 1.0,
12+
});
2313

24-
const fmInitial = await getRecentTracks(
25-
env.LASTFM_API_KEY,
26-
env.LASTFM_USERNAME,
27-
1,
28-
size,
29-
startFrom,
30-
);
31-
if (fmInitial === null) {
32-
console.error("Fail - No tracks returned from initial api request.");
33-
return new Response("error", { headers: { "Content-Type": "text/plain" } });
34-
}
35-
const paginationInitial = fmInitial.recenttracks["@attr"];
36-
totalPages = parseInt(paginationInitial.totalPages);
37-
total = parseInt(paginationInitial.total);
38-
page = totalPages;
14+
// Set region and execution_id as custom tags
15+
Sentry.setTag("region", Deno.env.get("SB_REGION"));
16+
Sentry.setTag("execution_id", Deno.env.get("SB_EXECUTION_ID"));
17+
Sentry.setTag("url", env.SUPABASE_URL);
3918

40-
if (startFrom) {
41-
console.log(
42-
`Found ${total} new tracks to save! Starting from page ${totalPages}.`,
43-
);
44-
} else {
45-
console.log(
46-
`Found ${total} tracks in total. Starting from page ${totalPages}.`,
47-
);
19+
Deno.serve(async () => {
20+
try {
21+
const result = await scrobbles(env);
22+
return new Response(result, {
23+
status: 200,
24+
headers: { "Content-Type": "text/plain" },
25+
});
26+
} catch (e) {
27+
Sentry.captureException(e);
28+
return new Response("error occured, please check sentry/supabase logs", {
29+
status: 500,
30+
headers: { "Content-Type": "text/plain" },
31+
});
4832
}
49-
50-
let processedPages = 0;
51-
do {
52-
if (processedPages === 10) {
53-
console.log(
54-
`Already inserted ${
55-
processedPages * size
56-
} items to db. Stopped. See ya in next cron.`,
57-
);
58-
break;
59-
}
60-
61-
const fm = await getRecentTracks(
62-
env.LASTFM_API_KEY,
63-
env.LASTFM_USERNAME,
64-
page,
65-
size,
66-
startFrom,
67-
);
68-
if (fm === null) {
69-
console.error("Fail - No tracks returned from api request.");
70-
break;
71-
}
72-
const data = fm.recenttracks;
73-
const tracks = data.track;
74-
75-
if (total === 0 || tracks.length === 0) {
76-
break;
77-
}
78-
79-
console.log(`Fetching page ${page}/${totalPages}`);
80-
81-
const toInsert: Row[] = tracks
82-
.filter((track) => !(track["@attr"] && track["@attr"].nowplaying))
83-
.map((track) => ({
84-
created_at: new Date().toISOString(),
85-
listened_at: new Date(track.date!.uts * 1000).toISOString(),
86-
artist_name: track.artist.name,
87-
track_name: track.name,
88-
album_name: track.album["#text"],
89-
lastfm_data: track,
90-
}));
91-
92-
const { error, message } = await table.save(toInsert);
93-
if (error) {
94-
break;
95-
}
96-
97-
if (message) {
98-
console.log(message);
99-
}
100-
101-
processedPages++;
102-
page--;
103-
} while (page >= 1);
104-
105-
return new Response("ok1", { headers: { "Content-Type": "text/plain" } });
10633
});
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { createClient } from "https://esm.sh/@supabase/supabase-js@2";
2+
import { getRecentTracks } from "./lastfm.ts";
3+
import { Row, TableListened } from "./table.ts";
4+
import { Variables } from "./env.ts";
5+
6+
export async function scrobbles(env: Variables): Promise<string> {
7+
const size = 50;
8+
const supabaseClient = createClient(env.SUPABASE_URL, env.SUPABASE_ANON_KEY);
9+
const table = new TableListened(supabaseClient);
10+
const startFrom: number | null = await table.getLastListenedDate();
11+
let totalPages = 1;
12+
let total = 0;
13+
let page = 1;
14+
15+
if (startFrom) {
16+
console.log(
17+
"Starting from last listened date:",
18+
new Date(startFrom * 1000).toLocaleString(),
19+
);
20+
} else {
21+
console.log("Database is empty, starting from the last page");
22+
}
23+
24+
const fmInitial = await getRecentTracks(
25+
env.LASTFM_API_KEY,
26+
env.LASTFM_USERNAME,
27+
1,
28+
size,
29+
startFrom,
30+
);
31+
if (fmInitial === null) {
32+
throw new Error("Fail - No tracks returned from initial api request.");
33+
}
34+
const paginationInitial = fmInitial.recenttracks["@attr"];
35+
totalPages = parseInt(paginationInitial.totalPages);
36+
total = parseInt(paginationInitial.total);
37+
page = totalPages;
38+
39+
if (startFrom) {
40+
console.log(
41+
`Found ${total} new tracks to save! Starting from page ${totalPages}.`,
42+
);
43+
} else {
44+
console.log(
45+
`Found ${total} tracks in total. Starting from page ${totalPages}.`,
46+
);
47+
}
48+
49+
let processedPages = 0;
50+
do {
51+
if (processedPages === 10) {
52+
console.log(
53+
`Already inserted ${
54+
processedPages * size
55+
} items to db. Stopped. See ya in next cron.`,
56+
);
57+
break;
58+
}
59+
60+
const fm = await getRecentTracks(
61+
env.LASTFM_API_KEY,
62+
env.LASTFM_USERNAME,
63+
page,
64+
size,
65+
startFrom,
66+
);
67+
if (fm === null) {
68+
console.warn("Fail - No tracks returned from api request.");
69+
break;
70+
}
71+
const data = fm.recenttracks;
72+
const tracks = data.track;
73+
74+
if (total === 0 || tracks.length === 0) {
75+
break;
76+
}
77+
78+
console.log(`Fetching page ${page}/${totalPages}`);
79+
80+
const toInsert: Row[] = tracks
81+
.filter((track) => !(track["@attr"] && track["@attr"].nowplaying))
82+
.map((track) => ({
83+
created_at: new Date().toISOString(),
84+
listened_at: new Date(track.date!.uts * 1000).toISOString(),
85+
artist_name: track.artist.name,
86+
track_name: track.name,
87+
album_name: track.album["#text"],
88+
lastfm_data: track,
89+
}));
90+
91+
const { error, message } = await table.save(toInsert);
92+
if (error) {
93+
throw new Error(error.toString());
94+
}
95+
96+
if (message) {
97+
console.log(message);
98+
}
99+
100+
processedPages++;
101+
page--;
102+
} while (page >= 1);
103+
104+
return "ok";
105+
}

0 commit comments

Comments
 (0)