Skip to content

Commit 5f08082

Browse files
authored
chore: add public API alerting (#4089)
Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
1 parent 2cd9fb4 commit 5f08082

5 files changed

Lines changed: 37 additions & 3 deletions

File tree

backend/src/api/public/middlewares/errorHandler.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,13 @@ import {
44
UnauthorizedError as Auth0UnauthorizedError,
55
} from 'express-oauth2-jwt-bearer'
66

7-
import { HttpError, InsufficientScopeError, InternalError, UnauthorizedError } from '@crowd/common'
7+
import {
8+
ConflictError,
9+
HttpError,
10+
InsufficientScopeError,
11+
InternalError,
12+
UnauthorizedError,
13+
} from '@crowd/common'
814
import { SlackChannel, SlackPersona, sendSlackNotification } from '@crowd/slack'
915

1016
/**
@@ -17,6 +23,30 @@ export const errorHandler: ErrorRequestHandler = (
1723
res: Response,
1824
_next: NextFunction,
1925
) => {
26+
if (error instanceof ConflictError) {
27+
req.log.warn({ context: error.context }, 'Public API conflict')
28+
sendSlackNotification(
29+
SlackChannel.CDP_LFX_SELF_SERVE_ALERTS,
30+
SlackPersona.WARNING_PROPAGATOR,
31+
`Public API Conflict 409: ${req.method} ${req.url}`,
32+
[
33+
{
34+
title: 'Request',
35+
text: `*Method:* \`${req.method}\`\n*URL:* \`${req.url}\``,
36+
},
37+
{
38+
title: 'Conflict',
39+
text: `*Message:* ${error.message}`,
40+
},
41+
...(error.context
42+
? [{ title: 'Context', text: `\`\`\`${JSON.stringify(error.context, null, 2)}\`\`\`` }]
43+
: []),
44+
],
45+
)
46+
res.status(error.status).json(error.toJSON())
47+
return
48+
}
49+
2050
if (error instanceof HttpError) {
2151
res.status(error.status).json(error.toJSON())
2252
return

backend/src/api/public/v1/members/resolveMember.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export async function resolveMemberByIdentities(req: Request, res: Response): Pr
3232
if (memberIds.length === 0) {
3333
throw new NotFoundError('Member not found')
3434
} else if (memberIds.length > 1) {
35-
throw new ConflictError('Conflicting identities')
35+
throw new ConflictError('Conflicting identities', { memberIds })
3636
}
3737

3838
const memberId = memberIds[0]

services/libs/common/src/errors/http.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,11 @@ export class NotFoundError extends HttpError {
7070
export class ConflictError extends HttpError {
7171
readonly code = 'CONFLICT'
7272
readonly status = 409
73+
readonly context?: Record<string, unknown>
7374

74-
constructor(message = 'Conflict') {
75+
constructor(message = 'Conflict', context?: Record<string, unknown>) {
7576
super(message)
77+
this.context = context
7678
}
7779
}
7880

services/libs/slack/src/channels.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const CHANNEL_WEBHOOK_URLS: Record<SlackChannel, string | undefined> = {
1212
[SlackChannel.CDP_PROJECTS_ALERTS]: process.env.CDP_PROJECTS_ALERTS_SLACK_WEBHOOK_URL,
1313
[SlackChannel.INSIGHTS_ALERTS]: process.env.INSIGHTS_ALERTS_SLACK_WEBHOOK_URL,
1414
[SlackChannel.INSIGHTS_CRITICAL_ALERTS]: process.env.INSIGHTS_CRITICAL_ALERTS_SLACK_WEBHOOK_URL,
15+
[SlackChannel.CDP_LFX_SELF_SERVE_ALERTS]: process.env.CDP_LFX_SELF_SERVE_ALERTS_SLACK_WEBHOOK_URL,
1516
}
1617

1718
// Check for missing webhook URLs on initialization

services/libs/slack/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export enum SlackChannel {
66
CDP_PROJECTS_ALERTS = 'CDP_PROJECTS_ALERTS',
77
INSIGHTS_ALERTS = 'INSIGHTS_ALERTS',
88
INSIGHTS_CRITICAL_ALERTS = 'INSIGHTS_CRITICAL_ALERTS',
9+
CDP_LFX_SELF_SERVE_ALERTS = 'CDP_LFX_SELF_SERVE_ALERTS',
910
}
1011

1112
export enum SlackPersona {

0 commit comments

Comments
 (0)