From 3a2bbbb8501f7238dba0dc124234e9e0459cdd9e Mon Sep 17 00:00:00 2001 From: Bogdan Ilchyshyn Date: Wed, 29 Jun 2022 15:59:51 +1000 Subject: [PATCH] support error handling in middleware (#12716) --- .../typescript-fetch/runtime.mustache | 36 ++++++++++++++++++- .../builds/default-v3.0/runtime.ts | 36 ++++++++++++++++++- .../builds/default/runtime.ts | 36 ++++++++++++++++++- .../typescript-fetch/builds/enum/runtime.ts | 36 ++++++++++++++++++- .../builds/es6-target/src/runtime.ts | 36 ++++++++++++++++++- .../builds/multiple-parameters/runtime.ts | 36 ++++++++++++++++++- .../src/runtime.ts | 36 ++++++++++++++++++- .../builds/sagas-and-records/src/runtime.ts | 36 ++++++++++++++++++- .../builds/with-interfaces/runtime.ts | 36 ++++++++++++++++++- .../builds/with-npm-version/src/runtime.ts | 36 ++++++++++++++++++- .../builds/with-string-enums/runtime.ts | 36 ++++++++++++++++++- .../without-runtime-checks/src/runtime.ts | 36 ++++++++++++++++++- 12 files changed, 420 insertions(+), 12 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache b/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache index 5dacb67bf55..d4644d543ff 100644 --- a/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache +++ b/modules/openapi-generator/src/main/resources/typescript-fetch/runtime.mustache @@ -166,7 +166,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -207,6 +225,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -315,9 +340,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse { diff --git a/samples/client/petstore/typescript-fetch/builds/default-v3.0/runtime.ts b/samples/client/petstore/typescript-fetch/builds/default-v3.0/runtime.ts index 1ab0a775e9c..01a6b3b2bd4 100644 --- a/samples/client/petstore/typescript-fetch/builds/default-v3.0/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/default-v3.0/runtime.ts @@ -177,7 +177,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -218,6 +236,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -322,9 +347,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse { diff --git a/samples/client/petstore/typescript-fetch/builds/default/runtime.ts b/samples/client/petstore/typescript-fetch/builds/default/runtime.ts index fd8de02dd81..add595fb797 100644 --- a/samples/client/petstore/typescript-fetch/builds/default/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/default/runtime.ts @@ -177,7 +177,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -218,6 +236,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -322,9 +347,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse { diff --git a/samples/client/petstore/typescript-fetch/builds/enum/runtime.ts b/samples/client/petstore/typescript-fetch/builds/enum/runtime.ts index cd6f5def237..99d8d846c83 100644 --- a/samples/client/petstore/typescript-fetch/builds/enum/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/enum/runtime.ts @@ -177,7 +177,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -218,6 +236,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -322,9 +347,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse { diff --git a/samples/client/petstore/typescript-fetch/builds/es6-target/src/runtime.ts b/samples/client/petstore/typescript-fetch/builds/es6-target/src/runtime.ts index fd8de02dd81..add595fb797 100644 --- a/samples/client/petstore/typescript-fetch/builds/es6-target/src/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/es6-target/src/runtime.ts @@ -177,7 +177,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -218,6 +236,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -322,9 +347,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse { diff --git a/samples/client/petstore/typescript-fetch/builds/multiple-parameters/runtime.ts b/samples/client/petstore/typescript-fetch/builds/multiple-parameters/runtime.ts index fd8de02dd81..add595fb797 100644 --- a/samples/client/petstore/typescript-fetch/builds/multiple-parameters/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/multiple-parameters/runtime.ts @@ -177,7 +177,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -218,6 +236,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -322,9 +347,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse { diff --git a/samples/client/petstore/typescript-fetch/builds/prefix-parameter-interfaces/src/runtime.ts b/samples/client/petstore/typescript-fetch/builds/prefix-parameter-interfaces/src/runtime.ts index fd8de02dd81..add595fb797 100644 --- a/samples/client/petstore/typescript-fetch/builds/prefix-parameter-interfaces/src/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/prefix-parameter-interfaces/src/runtime.ts @@ -177,7 +177,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -218,6 +236,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -322,9 +347,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse { diff --git a/samples/client/petstore/typescript-fetch/builds/sagas-and-records/src/runtime.ts b/samples/client/petstore/typescript-fetch/builds/sagas-and-records/src/runtime.ts index fd8de02dd81..add595fb797 100644 --- a/samples/client/petstore/typescript-fetch/builds/sagas-and-records/src/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/sagas-and-records/src/runtime.ts @@ -177,7 +177,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -218,6 +236,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -322,9 +347,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse { diff --git a/samples/client/petstore/typescript-fetch/builds/with-interfaces/runtime.ts b/samples/client/petstore/typescript-fetch/builds/with-interfaces/runtime.ts index fd8de02dd81..add595fb797 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-interfaces/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-interfaces/runtime.ts @@ -177,7 +177,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -218,6 +236,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -322,9 +347,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse { diff --git a/samples/client/petstore/typescript-fetch/builds/with-npm-version/src/runtime.ts b/samples/client/petstore/typescript-fetch/builds/with-npm-version/src/runtime.ts index fd8de02dd81..add595fb797 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-npm-version/src/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-npm-version/src/runtime.ts @@ -177,7 +177,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -218,6 +236,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -322,9 +347,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse { diff --git a/samples/client/petstore/typescript-fetch/builds/with-string-enums/runtime.ts b/samples/client/petstore/typescript-fetch/builds/with-string-enums/runtime.ts index cd6f5def237..99d8d846c83 100644 --- a/samples/client/petstore/typescript-fetch/builds/with-string-enums/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/with-string-enums/runtime.ts @@ -177,7 +177,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -218,6 +236,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -322,9 +347,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse { diff --git a/samples/client/petstore/typescript-fetch/builds/without-runtime-checks/src/runtime.ts b/samples/client/petstore/typescript-fetch/builds/without-runtime-checks/src/runtime.ts index 3e4ccfc28f2..55c164497f8 100644 --- a/samples/client/petstore/typescript-fetch/builds/without-runtime-checks/src/runtime.ts +++ b/samples/client/petstore/typescript-fetch/builds/without-runtime-checks/src/runtime.ts @@ -177,7 +177,25 @@ export class BaseAPI { }) || fetchParams; } } - let response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + let response = undefined; + try { + response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init); + } catch (e) { + for (const middleware of this.middleware) { + if (middleware.onError) { + response = await middleware.onError({ + fetch: this.fetchApi, + url: fetchParams.url, + init: fetchParams.init, + error: e, + response: response ? response.clone() : undefined, + }) || response; + } + } + if (response !== undefined) { + throw new FetchError(e, 'The request failed and the interceptors did not return an alternative response'); + } + } for (const middleware of this.middleware) { if (middleware.post) { response = await middleware.post({ @@ -218,6 +236,13 @@ export class ResponseError extends Error { } } +export class FetchError extends Error { + name: "FetchError" = "FetchError"; + constructor(public cause: unknown, msg?: string) { + super(msg); + } +} + export class RequiredError extends Error { name: "RequiredError" = "RequiredError"; constructor(public field: string, msg?: string) { @@ -312,9 +337,18 @@ export interface ResponseContext { response: Response; } +export interface ErrorContext { + fetch: FetchAPI; + url: string; + init: RequestInit; + error: unknown; + response?: Response; +} + export interface Middleware { pre?(context: RequestContext): Promise; post?(context: ResponseContext): Promise; + onError?(context: ErrorContext): Promise; } export interface ApiResponse {