This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

feat: add upload sentry logging and better errors

+113 -55
+113 -55
src/features/takes/services/upload.ts
··· 3 3 import { takes as takesTable } from "../../../libs/schema"; 4 4 import { eq, and } from "drizzle-orm"; 5 5 import { prettyPrintTime } from "../../../libs/time"; 6 - import { calculateElapsedTime } from "../../../libs/time-periods"; 6 + import * as Sentry from "@sentry/bun"; 7 7 8 8 export default async function upload() { 9 9 slackApp.anyMessage(async ({ payload }) => { ··· 224 224 }); 225 225 } catch (error) { 226 226 console.error("Error handling file message:", error); 227 + await slackClient.chat.postMessage({ 228 + channel: payload.channel, 229 + thread_ts: payload.thread_ts, 230 + text: ":warning: there was an error processing your upload", 231 + }); 232 + 233 + Sentry.captureException(error, { 234 + extra: { 235 + channel: payload.channel, 236 + user: payload.user, 237 + thread_ts: payload.thread_ts, 238 + }, 239 + tags: { 240 + type: "file_upload_error", 241 + }, 242 + }); 227 243 } 228 244 }); 229 245 230 246 slackApp.action("select_multiplier", async () => {}); 231 247 232 248 slackApp.action("approve", async ({ payload, context }) => { 233 - const multiplier = Object.values(payload.state.values)[0] 234 - ?.select_multiplier?.selected_option?.value; 235 - // @ts-expect-error 236 - const takeId = payload.actions[0]?.value; 249 + try { 250 + const multiplier = Object.values(payload.state.values)[0] 251 + ?.select_multiplier?.selected_option?.value; 252 + // @ts-expect-error 253 + const takeId = payload.actions[0]?.value; 237 254 238 - const take = await db 239 - .select() 240 - .from(takesTable) 241 - .where(eq(takesTable.id, takeId)); 242 - if (take.length === 0) { 243 - return; 244 - } 245 - const takeToApprove = take[0]; 246 - if (!takeToApprove) return; 255 + const take = await db 256 + .select() 257 + .from(takesTable) 258 + .where(eq(takesTable.id, takeId)); 259 + if (take.length === 0) { 260 + return; 261 + } 262 + const takeToApprove = take[0]; 263 + if (!takeToApprove) return; 264 + 265 + await db 266 + .update(takesTable) 267 + .set({ 268 + status: "approved", 269 + multiplier: multiplier, 270 + }) 271 + .where(eq(takesTable.id, takeId)); 247 272 248 - await db 249 - .update(takesTable) 250 - .set({ 251 - status: "approved", 252 - multiplier: multiplier, 253 - }) 254 - .where(eq(takesTable.id, takeId)); 273 + await slackClient.chat.postMessage({ 274 + channel: payload.user.id, 275 + thread_ts: take[0]?.ts as string, 276 + text: `take approved with multiplier \`${multiplier}\` so you have earned *${Number((takeToApprove.elapsedTimeMs * Number(multiplier)) / 60).toFixed(1)} takes*!`, 277 + }); 255 278 256 - await slackClient.chat.postMessage({ 257 - channel: payload.user.id, 258 - thread_ts: take[0]?.ts as string, 259 - text: `take approved with multiplier \`${multiplier}\` so you have earned *${Number((takeToApprove.elapsedTimeMs * Number(multiplier)) / 60).toFixed(1)} takes*!`, 260 - }); 279 + // delete the message from the review channel 280 + if (context.respond) 281 + await context.respond({ 282 + delete_original: true, 283 + }); 284 + } catch (error) { 285 + console.error("Error approving take:", error); 261 286 262 - // delete the message from the review channel 263 - if (context.respond) 264 - await context.respond({ 265 - delete_original: true, 287 + await slackClient.chat.postEphemeral({ 288 + channel: process.env.SLACK_REVIEW_CHANNEL || "", 289 + user: payload.user.id, 290 + text: ":warning: there was an error approving the take", 266 291 }); 292 + 293 + Sentry.captureException(error, { 294 + extra: { 295 + // @ts-expect-error 296 + take: payload.actions[0]?.value, 297 + userApproving: payload.user, 298 + }, 299 + tags: { 300 + type: "take_approve_error", 301 + }, 302 + }); 303 + } 267 304 }); 268 305 269 306 slackApp.action("reject", async ({ payload, context }) => { 270 - // @ts-expect-error 271 - const takeId = payload.actions[0]?.value; 307 + try { 308 + // @ts-expect-error 309 + const takeId = payload.actions[0]?.value; 272 310 273 - const take = await db 274 - .select() 275 - .from(takesTable) 276 - .where(eq(takesTable.id, takeId)); 277 - if (take.length === 0) { 278 - return; 279 - } 280 - await db 281 - .update(takesTable) 282 - .set({ 283 - status: "rejected", 284 - multiplier: "0", 285 - }) 286 - .where(eq(takesTable.id, takeId)); 311 + const take = await db 312 + .select() 313 + .from(takesTable) 314 + .where(eq(takesTable.id, takeId)); 315 + if (take.length === 0) { 316 + return; 317 + } 318 + await db 319 + .update(takesTable) 320 + .set({ 321 + status: "rejected", 322 + multiplier: "0", 323 + }) 324 + .where(eq(takesTable.id, takeId)); 325 + 326 + await slackClient.chat.postMessage({ 327 + channel: payload.user.id, 328 + thread_ts: take[0]?.ts as string, 329 + text: "take rejected :(", 330 + }); 331 + 332 + // delete the message from the review channel 333 + if (context.respond) 334 + await context.respond({ 335 + delete_original: true, 336 + }); 337 + } catch (error) { 338 + console.error("Error rejecting take:", error); 287 339 288 - await slackClient.chat.postMessage({ 289 - channel: payload.user.id, 290 - thread_ts: take[0]?.ts as string, 291 - text: "take rejected :(", 292 - }); 340 + await slackClient.chat.postEphemeral({ 341 + channel: process.env.SLACK_REVIEW_CHANNEL || "", 342 + user: payload.user.id, 343 + text: ":warning: there was an error rejecting the take", 344 + }); 293 345 294 - // delete the message from the review channel 295 - if (context.respond) 296 - await context.respond({ 297 - delete_original: true, 346 + Sentry.captureException(error, { 347 + extra: { 348 + // @ts-expect-error 349 + take: payload.actions[0]?.value, 350 + userRejecting: payload.user, 351 + }, 352 + tags: { 353 + type: "take_reject_error", 354 + }, 298 355 }); 356 + } 299 357 }); 300 358 }