Skip to content

Commit

Permalink
fix: validation error body format (#17)
Browse files Browse the repository at this point in the history
* fix: validation error body format

* chore: bump proxy version

* chore: bump client version
  • Loading branch information
drochetti authored Oct 11, 2023
1 parent e02118f commit 0e3cb85
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 11 deletions.
2 changes: 1 addition & 1 deletion libs/client/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@fal-ai/serverless-client",
"description": "The fal serverless JS/TS client",
"version": "0.3.1",
"version": "0.3.2",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion libs/client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ export { withMiddleware, withProxy } from './middleware';
export type { RequestMiddleware } from './middleware';
export { ApiError, ValidationError } from './response';
export type { ResponseHandler } from './response';
export type { QueueStatus } from './types';
export type { QueueStatus, ValidationErrorInfo } from './types';
37 changes: 31 additions & 6 deletions libs/client/src/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,45 @@ export class ApiError<Body> extends Error {
}
}

export class ValidationError extends ApiError<ValidationErrorInfo[]> {
type ValidationErrorBody = {
detail: ValidationErrorInfo[];
};

export class ValidationError extends ApiError<ValidationErrorBody> {
constructor(args: ApiErrorArgs) {
super(args);
this.name = 'ValidationError';
}

get fieldErrors(): ValidationErrorInfo[] {
// NOTE: this is a hack to support both FastAPI/Pydantic errors
// and some custom 422 errors that might not be in the Pydantic format.
if (typeof this.body.detail === 'string') {
return [
{
loc: ['body'],
msg: this.body.detail,
type: 'value_error',
},
];
}
return this.body.detail || [];
}

getFieldErrors(field: string): ValidationErrorInfo[] {
return this.fieldErrors.filter(
(error) => error.loc[error.loc.length - 1] === field
);
}
}

export async function defaultResponseHandler<Output>(
response: Response
): Promise<Output> {
const { status, statusText } = response;
const contentType = response.headers.get('Content-Type');
const contentType = response.headers.get('Content-Type') ?? "";
if (!response.ok) {
if (contentType?.includes('application/json')) {
if (contentType.includes('application/json')) {
const body = await response.json();
const ErrorType = status === 422 ? ValidationError : ApiError;
throw new ErrorType({
Expand All @@ -44,13 +69,13 @@ export async function defaultResponseHandler<Output>(
}
throw new ApiError({ message: `HTTP ${status}: ${statusText}`, status });
}
if (contentType?.includes('application/json')) {
if (contentType.includes('application/json')) {
return response.json() as Promise<Output>;
}
if (contentType?.includes('text/html')) {
if (contentType.includes('text/html')) {
return response.text() as Promise<Output>;
}
if (contentType?.includes('application/octet-stream')) {
if (contentType.includes('application/octet-stream')) {
return response.arrayBuffer() as Promise<Output>;
}
// TODO convert to either number or bool automatically
Expand Down
2 changes: 1 addition & 1 deletion libs/proxy/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fal-ai/serverless-proxy",
"version": "0.3.4",
"version": "0.3.5",
"license": "MIT",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion libs/proxy/src/express.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const handler: RequestHandler = async (request, response, next) => {
method: request.method,
respondWith: (status, data) =>
typeof data === 'string'
? response.status(status).json({ details: data })
? response.status(status).json({ detail: data })
: response.status(status).json(data),
getHeaders: () => request.headers,
getHeader: (name) => request.headers[name],
Expand Down
2 changes: 1 addition & 1 deletion libs/proxy/src/nextjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const handler: NextApiHandler = async (request, response) => {
method: request.method,
respondWith: (status, data) =>
typeof data === 'string'
? response.status(status).json({ details: data })
? response.status(status).json({ detail: data })
: response.status(status).json(data),
getHeaders: () => request.headers,
getHeader: (name) => request.headers[name],
Expand Down

0 comments on commit 0e3cb85

Please sign in to comment.