fix(api): handle common errors better

This commit is contained in:
Carl-Gerhard Lindesvärd
2025-01-28 07:14:35 +00:00
parent 8bbf36473b
commit 7deee7e4c2
4 changed files with 63 additions and 7 deletions

View File

@@ -49,7 +49,7 @@ function getIdentity(body: TrackHandlerPayload): IdentifyPayload | undefined {
return (
identity ||
(body.payload.profileId
(body?.payload?.profileId
? {
profileId: body.payload.profileId,
}
@@ -100,7 +100,11 @@ export async function handler(
const projectId = request.client?.projectId;
if (!projectId) {
reply.status(400).send('missing origin');
reply.status(400).send({
status: 400,
error: 'Bad Request',
message: 'Missing projectId',
});
return;
}
@@ -198,6 +202,14 @@ export async function handler(
});
break;
}
default: {
reply.status(400).send({
status: 400,
error: 'Bad Request',
message: 'Invalid type',
});
break;
}
}
}

View File

@@ -208,6 +208,12 @@ const startServer = async () => {
error: 'Too Many Requests',
message: 'You have exceeded the rate limit for this endpoint.',
});
} else if (error.statusCode === 400) {
reply.status(400).send({
status: 400,
error,
message: 'The request was invalid.',
});
} else {
request.log.error('request error', { error });
reply.status(500).send('Internal server error');

View File

@@ -1,12 +1,8 @@
import { isBot } from '@/bots';
import { handler } from '@/controllers/track.controller';
import { SdkAuthError, validateSdkRequest } from '@/utils/auth';
import type { FastifyPluginCallback, FastifyRequest } from 'fastify';
import type { FastifyPluginCallback } from 'fastify';
import { clientHook } from '@/hooks/client.hook';
import { isBotHook } from '@/hooks/is-bot.hook';
import { createBotEvent } from '@openpanel/db';
import type { TrackHandlerPayload } from '@openpanel/sdk';
const trackRouter: FastifyPluginCallback = (fastify, opts, done) => {
fastify.addHook('preHandler', clientHook);
@@ -16,6 +12,22 @@ const trackRouter: FastifyPluginCallback = (fastify, opts, done) => {
method: 'POST',
url: '/',
handler: handler,
schema: {
body: {
type: 'object',
required: ['type', 'payload'],
properties: {
type: {
type: 'string',
enum: ['track', 'increment', 'decrement', 'alias', 'identify'],
},
payload: {
type: 'object',
additionalProperties: true,
},
},
},
},
});
done();

View File

@@ -66,6 +66,14 @@ export async function validateSdkRequest(
throw createError('Ingestion: Missing client id');
}
if (
!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(
clientId,
)
) {
throw createError('Ingestion: Clean ID must be a valid UUIDv4');
}
const client = await getClientByIdCached(clientId);
if (!client) {
@@ -136,6 +144,15 @@ export async function validateExportRequest(
): Promise<IServiceClientWithProject> {
const clientId = headers['openpanel-client-id'] as string;
const clientSecret = (headers['openpanel-client-secret'] as string) || '';
if (
!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(
clientId,
)
) {
throw new Error('Export: Client ID must be a valid UUIDv4');
}
const client = await getClientByIdCached(clientId);
if (!client) {
@@ -162,6 +179,15 @@ export async function validateImportRequest(
): Promise<IServiceClientWithProject> {
const clientId = headers['openpanel-client-id'] as string;
const clientSecret = (headers['openpanel-client-secret'] as string) || '';
if (
!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(
clientId,
)
) {
throw new Error('Import: Client ID must be a valid UUIDv4');
}
const client = await getClientByIdCached(clientId);
if (!client) {