diff --git a/apps/e2e/src/__snapshots__/e2e.test.ts.snap b/apps/e2e/src/__snapshots__/e2e.test.ts.snap index 756fbbea..50e54fb6 100644 --- a/apps/e2e/src/__snapshots__/e2e.test.ts.snap +++ b/apps/e2e/src/__snapshots__/e2e.test.ts.snap @@ -1,5 +1,41 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`Basic GET caching > 3.0: GET dev/test-basic-openapi@b6e21206/getPost 1`] = ` +{ + "body": "consectetur animi nesciunt iure dolore +enim quia ad +veniam autem ut quam aut nobis +et est aut quod aut provident voluptas autem voluptas", + "id": 9, + "title": "nesciunt iure omnis dolorem tempora et accusantium", + "userId": 1, +} +`; + +exports[`Basic GET caching > 3.1: GET dev/test-basic-openapi@b6e21206/getPost?postId=9 1`] = ` +{ + "body": "consectetur animi nesciunt iure dolore +enim quia ad +veniam autem ut quam aut nobis +et est aut quod aut provident voluptas autem voluptas", + "id": 9, + "title": "nesciunt iure omnis dolorem tempora et accusantium", + "userId": 1, +} +`; + +exports[`Basic GET caching > 3.2: GET dev/test-basic-openapi@b6e21206/get_post?postId=9 1`] = ` +{ + "body": "consectetur animi nesciunt iure dolore +enim quia ad +veniam autem ut quam aut nobis +et est aut quod aut provident voluptas autem voluptas", + "id": 9, + "title": "nesciunt iure omnis dolorem tempora et accusantium", + "userId": 1, +} +`; + exports[`Basic OpenAPI getPost(1) > 0.0: GET dev/test-basic-openapi/getPost 1`] = ` { "body": "quia et suscipit @@ -71,3 +107,51 @@ nostrum rerum est autem sunt rem eveniet architecto", "userId": 1, } `; + +exports[`Bypass caching > 2.0: GET dev/test-basic-openapi@b6e21206/getPost 1`] = ` +{ + "body": "consectetur animi nesciunt iure dolore +enim quia ad +veniam autem ut quam aut nobis +et est aut quod aut provident voluptas autem voluptas", + "id": 9, + "title": "nesciunt iure omnis dolorem tempora et accusantium", + "userId": 1, +} +`; + +exports[`Bypass caching > 2.1: GET dev/test-basic-openapi@b6e21206/getPost?postId=9 1`] = ` +{ + "body": "consectetur animi nesciunt iure dolore +enim quia ad +veniam autem ut quam aut nobis +et est aut quod aut provident voluptas autem voluptas", + "id": 9, + "title": "nesciunt iure omnis dolorem tempora et accusantium", + "userId": 1, +} +`; + +exports[`Bypass caching > 2.2: GET dev/test-basic-openapi@b6e21206/get_post?postId=9 1`] = ` +{ + "body": "consectetur animi nesciunt iure dolore +enim quia ad +veniam autem ut quam aut nobis +et est aut quod aut provident voluptas autem voluptas", + "id": 9, + "title": "nesciunt iure omnis dolorem tempora et accusantium", + "userId": 1, +} +`; + +exports[`Bypass caching > 2.3: GET dev/test-basic-openapi@b6e21206/get_post?postId=9 1`] = ` +{ + "body": "consectetur animi nesciunt iure dolore +enim quia ad +veniam autem ut quam aut nobis +et est aut quod aut provident voluptas autem voluptas", + "id": 9, + "title": "nesciunt iure omnis dolorem tempora et accusantium", + "userId": 1, +} +`; diff --git a/apps/e2e/src/fixtures.ts b/apps/e2e/src/fixtures.ts index bac0fbc8..f6b70cd1 100644 --- a/apps/e2e/src/fixtures.ts +++ b/apps/e2e/src/fixtures.ts @@ -125,5 +125,94 @@ export const fixtureSuites: E2ETestFixtureSuite[] = [ } } ] + }, + { + title: 'Bypass caching', + fixtures: [ + { + path: 'dev/test-basic-openapi@b6e21206/getPost', + request: { + headers: { + pragma: 'no-cache' + }, + searchParams: { + postId: 9 + } + }, + response: { + headers: { + 'cf-cache-status': 'BYPASS' + } + } + }, + { + path: 'dev/test-basic-openapi@b6e21206/getPost?postId=9', + request: { + headers: { + 'cache-control': 'no-cache' + } + }, + response: { + headers: { + 'cf-cache-status': 'BYPASS' + } + } + }, + { + path: 'dev/test-basic-openapi@b6e21206/get_post?postId=9', + request: { + headers: { + 'cache-control': 'no-store' + } + }, + response: { + headers: { + 'cf-cache-status': 'BYPASS' + } + } + }, + { + path: 'dev/test-basic-openapi@b6e21206/get_post?postId=9', + request: { + headers: { + 'cache-control': 'max-age=0, must-revalidate, no-cache' + } + }, + response: { + headers: { + 'cf-cache-status': 'BYPASS' + } + } + } + ] + }, + { + title: 'Basic GET caching', + fixtures: [ + { + path: 'dev/test-basic-openapi@b6e21206/getPost', + request: { + searchParams: { + postId: 9 + } + } + }, + { + path: 'dev/test-basic-openapi@b6e21206/getPost?postId=9', + response: { + headers: { + 'cf-cache-status': 'HIT' + } + } + }, + { + path: 'dev/test-basic-openapi@b6e21206/get_post?postId=9', + response: { + headers: { + 'cf-cache-status': 'HIT' + } + } + } + ] } ] diff --git a/apps/gateway/src/worker.ts b/apps/gateway/src/worker.ts index 2db3ad54..7658df96 100644 --- a/apps/gateway/src/worker.ts +++ b/apps/gateway/src/worker.ts @@ -137,15 +137,12 @@ export default { try { parsedEnv = parseEnv(env) } catch (err: any) { - // TODO: Better error handling - return new Response( - JSON.stringify({ - error: err.message, - type: err.type, - code: err.code - }), - { status: 500 } - ) + return new Response(JSON.stringify({ error: err.message }), { + status: 500, + headers: { + 'content-type': 'application/json' + } + }) } return app.fetch(request, parsedEnv, ctx) diff --git a/packages/core/src/errors.ts b/packages/core/src/errors.ts index d19d1ab7..8e7a3da3 100644 --- a/packages/core/src/errors.ts +++ b/packages/core/src/errors.ts @@ -33,9 +33,17 @@ export class HttpError extends BaseError { } } -export class ZodValidationError extends BaseError { - constructor({ prefix, cause }: { prefix?: string; cause: unknown }) { +export class ZodValidationError extends HttpError { + constructor({ + statusCode, + prefix, + cause + }: { + statusCode?: ContentfulStatusCode + prefix?: string + cause: unknown + }) { const error = fromError(cause, { prefix }) - super({ message: error.message, cause }) + super({ message: error.message, cause, statusCode }) } } diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index acb0aaea..1260606a 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -82,9 +82,11 @@ export function parseZodSchema>( schema: TSchema, input: unknown, { - error + error, + statusCode = 500 }: { error?: string + statusCode?: ContentfulStatusCode } = {} ): z.infer { try { @@ -92,7 +94,8 @@ export function parseZodSchema>( } catch (err) { throw new ZodValidationError({ prefix: error, - cause: err + cause: err, + statusCode }) } } diff --git a/packages/openapi-utils/src/get-tools-from-openapi-spec.ts b/packages/openapi-utils/src/get-tools-from-openapi-spec.ts index d9296792..8cfda9e5 100644 --- a/packages/openapi-utils/src/get-tools-from-openapi-spec.ts +++ b/packages/openapi-utils/src/get-tools-from-openapi-spec.ts @@ -191,12 +191,18 @@ export async function getToolsFromOpenAPISpec( const { tags } = operation tools.push( - parseZodSchema(toolSchema, { - name: operationNameSnakeCase, - description, - inputSchema: operationParamsJsonSchema, - outputSchema: operationResponseJsonSchema - }) + parseZodSchema( + toolSchema, + { + name: operationNameSnakeCase, + description, + inputSchema: operationParamsJsonSchema, + outputSchema: operationResponseJsonSchema + }, + { + statusCode: 400 + } + ) ) toolToOperationMap[operationNameSnakeCase] = parseZodSchema( @@ -207,6 +213,9 @@ export async function getToolsFromOpenAPISpec( path, parameterSources: operationParamsSources, tags + }, + { + statusCode: 400 } ) } diff --git a/packages/platform/src/parse-agentic-project-config.ts b/packages/platform/src/parse-agentic-project-config.ts index cbbdccc3..2d8fb2dc 100644 --- a/packages/platform/src/parse-agentic-project-config.ts +++ b/packages/platform/src/parse-agentic-project-config.ts @@ -24,7 +24,10 @@ export function parseAgenticProjectConfig( : strict ? agenticProjectConfigSchema.strict() : agenticProjectConfigSchema, - inputConfig + inputConfig, + { + statusCode: 400 + } ) as AgenticProjectConfig } @@ -41,6 +44,9 @@ export function parseResolvedAgenticProjectConfig( : strict ? resolvedAgenticProjectConfigSchema.strict() : resolvedAgenticProjectConfigSchema, - inputConfig + inputConfig, + { + statusCode: 400 + } ) as ResolvedAgenticProjectConfig }