Improve ARM error parsing and display (#189)
This commit is contained in:
parent
af820c0fbf
commit
c401f88aae
|
@ -13,6 +13,7 @@ import DeleteFeedback from "../../Common/DeleteFeedback";
|
|||
import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils";
|
||||
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
|
||||
import { deleteDatabase } from "../../Common/dataAccess/deleteDatabase";
|
||||
import { ARMError } from "../../Utils/arm/request";
|
||||
|
||||
export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
|
||||
public databaseIdConfirmationText: ko.Observable<string>;
|
||||
|
@ -105,11 +106,12 @@ export default class DeleteDatabaseConfirmationPane extends ContextualPaneBase {
|
|||
this.databaseDeleteFeedback("");
|
||||
}
|
||||
},
|
||||
(reason: any) => {
|
||||
(reason: unknown) => {
|
||||
this.isExecuting(false);
|
||||
const message = ErrorParserUtility.parse(reason);
|
||||
this.formErrors(message[0].message);
|
||||
this.formErrorsDetails(message[0].message);
|
||||
|
||||
const message = reason instanceof ARMError ? reason.message : ErrorParserUtility.parse(reason)[0].message;
|
||||
this.formErrors(message);
|
||||
this.formErrorsDetails(message);
|
||||
TelemetryProcessor.traceFailure(
|
||||
Action.DeleteDatabase,
|
||||
{
|
||||
|
|
|
@ -6,11 +6,30 @@ Instead, generate ARM clients that consume this function with stricter typing.
|
|||
*/
|
||||
|
||||
import promiseRetry, { AbortError } from "p-retry";
|
||||
import { ErrorResponse } from "./generatedClients/2020-04-01/types";
|
||||
import { userContext } from "../../UserContext";
|
||||
|
||||
interface ARMError extends Error {
|
||||
interface ErrorResponse {
|
||||
code: string;
|
||||
message: string;
|
||||
}
|
||||
|
||||
// ARM sometimes returns an error wrapped in a top level error object
|
||||
// Example: 409 Conflict error when trying to delete a locked resource
|
||||
interface WrappedErrorResponse {
|
||||
error: ErrorResponse;
|
||||
}
|
||||
|
||||
type ParsedErrorResponse = ErrorResponse | WrappedErrorResponse;
|
||||
|
||||
export class ARMError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message);
|
||||
// Set the prototype explicitly.
|
||||
// https://github.com/Microsoft/TypeScript/wiki/FAQ#why-doesnt-extending-built-ins-like-error-array-and-map-work
|
||||
Object.setPrototypeOf(this, ARMError.prototype);
|
||||
}
|
||||
|
||||
public code: string | number;
|
||||
}
|
||||
|
||||
interface Options {
|
||||
|
@ -33,9 +52,20 @@ export async function armRequest<T>({ host, path, apiVersion, method, body: requ
|
|||
body: requestBody ? JSON.stringify(requestBody) : undefined
|
||||
});
|
||||
if (!response.ok) {
|
||||
const errorResponse = (await response.json()) as ErrorResponse;
|
||||
const error = new Error(errorResponse.message) as ARMError;
|
||||
let error: ARMError;
|
||||
try {
|
||||
const errorResponse = (await response.json()) as ParsedErrorResponse;
|
||||
if ("error" in errorResponse) {
|
||||
error = new ARMError(errorResponse.error.message);
|
||||
error.code = errorResponse.error.code;
|
||||
} else {
|
||||
error = new ARMError(errorResponse.message);
|
||||
error.code = errorResponse.code;
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(await response.text());
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue