fix: validation error body format (#17)
* fix: validation error body format * chore: bump proxy version * chore: bump client version
This commit is contained in:
parent
e02118f43f
commit
0e3cb85939
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@fal-ai/serverless-client",
|
"name": "@fal-ai/serverless-client",
|
||||||
"description": "The fal serverless JS/TS client",
|
"description": "The fal serverless JS/TS client",
|
||||||
"version": "0.3.1",
|
"version": "0.3.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@ -4,4 +4,4 @@ export { withMiddleware, withProxy } from './middleware';
|
|||||||
export type { RequestMiddleware } from './middleware';
|
export type { RequestMiddleware } from './middleware';
|
||||||
export { ApiError, ValidationError } from './response';
|
export { ApiError, ValidationError } from './response';
|
||||||
export type { ResponseHandler } from './response';
|
export type { ResponseHandler } from './response';
|
||||||
export type { QueueStatus } from './types';
|
export type { QueueStatus, ValidationErrorInfo } from './types';
|
||||||
|
|||||||
@ -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) {
|
constructor(args: ApiErrorArgs) {
|
||||||
super(args);
|
super(args);
|
||||||
this.name = 'ValidationError';
|
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>(
|
export async function defaultResponseHandler<Output>(
|
||||||
response: Response
|
response: Response
|
||||||
): Promise<Output> {
|
): Promise<Output> {
|
||||||
const { status, statusText } = response;
|
const { status, statusText } = response;
|
||||||
const contentType = response.headers.get('Content-Type');
|
const contentType = response.headers.get('Content-Type') ?? "";
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
if (contentType?.includes('application/json')) {
|
if (contentType.includes('application/json')) {
|
||||||
const body = await response.json();
|
const body = await response.json();
|
||||||
const ErrorType = status === 422 ? ValidationError : ApiError;
|
const ErrorType = status === 422 ? ValidationError : ApiError;
|
||||||
throw new ErrorType({
|
throw new ErrorType({
|
||||||
@ -44,13 +69,13 @@ export async function defaultResponseHandler<Output>(
|
|||||||
}
|
}
|
||||||
throw new ApiError({ message: `HTTP ${status}: ${statusText}`, status });
|
throw new ApiError({ message: `HTTP ${status}: ${statusText}`, status });
|
||||||
}
|
}
|
||||||
if (contentType?.includes('application/json')) {
|
if (contentType.includes('application/json')) {
|
||||||
return response.json() as Promise<Output>;
|
return response.json() as Promise<Output>;
|
||||||
}
|
}
|
||||||
if (contentType?.includes('text/html')) {
|
if (contentType.includes('text/html')) {
|
||||||
return response.text() as Promise<Output>;
|
return response.text() as Promise<Output>;
|
||||||
}
|
}
|
||||||
if (contentType?.includes('application/octet-stream')) {
|
if (contentType.includes('application/octet-stream')) {
|
||||||
return response.arrayBuffer() as Promise<Output>;
|
return response.arrayBuffer() as Promise<Output>;
|
||||||
}
|
}
|
||||||
// TODO convert to either number or bool automatically
|
// TODO convert to either number or bool automatically
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@fal-ai/serverless-proxy",
|
"name": "@fal-ai/serverless-proxy",
|
||||||
"version": "0.3.4",
|
"version": "0.3.5",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@ -19,7 +19,7 @@ export const handler: RequestHandler = async (request, response, next) => {
|
|||||||
method: request.method,
|
method: request.method,
|
||||||
respondWith: (status, data) =>
|
respondWith: (status, data) =>
|
||||||
typeof data === 'string'
|
typeof data === 'string'
|
||||||
? response.status(status).json({ details: data })
|
? response.status(status).json({ detail: data })
|
||||||
: response.status(status).json(data),
|
: response.status(status).json(data),
|
||||||
getHeaders: () => request.headers,
|
getHeaders: () => request.headers,
|
||||||
getHeader: (name) => request.headers[name],
|
getHeader: (name) => request.headers[name],
|
||||||
|
|||||||
@ -19,7 +19,7 @@ export const handler: NextApiHandler = async (request, response) => {
|
|||||||
method: request.method,
|
method: request.method,
|
||||||
respondWith: (status, data) =>
|
respondWith: (status, data) =>
|
||||||
typeof data === 'string'
|
typeof data === 'string'
|
||||||
? response.status(status).json({ details: data })
|
? response.status(status).json({ detail: data })
|
||||||
: response.status(status).json(data),
|
: response.status(status).json(data),
|
||||||
getHeaders: () => request.headers,
|
getHeaders: () => request.headers,
|
||||||
getHeader: (name) => request.headers[name],
|
getHeader: (name) => request.headers[name],
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user