refactor error handling part 1 (#307)

- created `getErrorMessage` function which takes in an error string or any type of error object and returns the correct error message
- replaced `error.message` with `getErrorMessage` since `error` could be a string in some cases
- merged sendNotificationForError.ts with ErrorHandlingUtils.ts
- some minor refactoring

In part 2, I will make the following changes:
 - Make `Logger.logError` function take an error message string instead of an error object. This will reduce some redundancy where the `getErrorMessage` function is being called twice (the error object passed by the caller is already an error message).
 - Update every `TelemetryProcessor.traceFailure` call to make sure we pass in an error message instead of an error object since we stringify the data we send.
This commit is contained in:
victor-meng 2020-10-30 15:09:24 -07:00 committed by GitHub
parent e2e58f73b1
commit 5741802c25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 162 additions and 159 deletions

View File

@ -1,6 +1,7 @@
import * as Cosmos from "@azure/cosmos"; import * as Cosmos from "@azure/cosmos";
import { RequestInfo, setAuthorizationTokenHeaderUsingMasterKey } from "@azure/cosmos"; import { RequestInfo, setAuthorizationTokenHeaderUsingMasterKey } from "@azure/cosmos";
import { configContext, Platform } from "../ConfigContext"; import { configContext, Platform } from "../ConfigContext";
import { getErrorMessage } from "./ErrorHandlingUtils";
import { logConsoleError } from "../Utils/NotificationConsoleUtils"; import { logConsoleError } from "../Utils/NotificationConsoleUtils";
import { EmulatorMasterKey, HttpHeaders } from "./Constants"; import { EmulatorMasterKey, HttpHeaders } from "./Constants";
import { userContext } from "../UserContext"; import { userContext } from "../UserContext";
@ -69,7 +70,7 @@ export async function getTokenFromAuthService(verb: string, resourceType: string
const result = JSON.parse(await response.json()); const result = JSON.parse(await response.json());
return result; return result;
} catch (error) { } catch (error) {
logConsoleError(`Failed to get authorization headers for ${resourceType}: ${error.message}`); logConsoleError(`Failed to get authorization headers for ${resourceType}: ${getErrorMessage(error)}`);
return Promise.reject(error); return Promise.reject(error);
} }
} }

View File

@ -1,11 +1,52 @@
import { CosmosError, sendNotificationForError } from "./dataAccess/sendNotificationForError"; import { HttpStatusCodes } from "./Constants";
import { MessageTypes } from "../Contracts/ExplorerContracts";
import { SubscriptionType } from "../Contracts/ViewModels";
import { logConsoleError } from "../Utils/NotificationConsoleUtils"; import { logConsoleError } from "../Utils/NotificationConsoleUtils";
import { logError } from "./Logger"; import { logError } from "./Logger";
import { replaceKnownError } from "./ErrorParserUtility"; import { sendMessage } from "./MessageHandler";
export const handleError = (error: CosmosError, consoleErrorPrefix: string, area: string): void => { export interface CosmosError {
const sanitizedErrorMsg = replaceKnownError(error.message); code: number;
logConsoleError(`${consoleErrorPrefix}:\n ${sanitizedErrorMsg}`); message?: string;
logError(sanitizedErrorMsg, area, error.code); }
sendNotificationForError(error);
export const handleError = (error: string | CosmosError, consoleErrorPrefix: string, area: string): void => {
const errorMessage = getErrorMessage(error);
const errorCode = typeof error === "string" ? undefined : error.code;
// logs error to data explorer console
logConsoleError(`${consoleErrorPrefix}:\n ${errorMessage}`);
// logs error to both app insight and kusto
logError(errorMessage, area, errorCode);
// checks for errors caused by firewall and sends them to portal to handle
sendNotificationForError(errorMessage, errorCode);
};
export const getErrorMessage = (error: string | CosmosError | Error): string => {
const errorMessage = typeof error === "string" ? error : error.message;
return replaceKnownError(errorMessage);
};
const sendNotificationForError = (errorMessage: string, errorCode: number): void => {
if (errorCode === HttpStatusCodes.Forbidden) {
if (errorMessage?.toLowerCase().indexOf("sharedoffer is disabled for your account") > 0) {
return;
}
sendMessage({
type: MessageTypes.ForbiddenError,
reason: errorMessage
});
}
};
const replaceKnownError = (errorMessage: string): string => {
if (
window.dataExplorer?.subscriptionType() === SubscriptionType.Internal &&
errorMessage.indexOf("SharedOffer is Disabled for your account") >= 0
) {
return "Database throughput is not supported for internal subscriptions.";
} else if (errorMessage.indexOf("Partition key paths must contain only valid") >= 0) {
return "Partition key paths must contain only valid characters and not contain a trailing slash or wildcard character.";
}
return errorMessage;
}; };

View File

@ -1,18 +1,4 @@
import * as DataModels from "../Contracts/DataModels"; import * as DataModels from "../Contracts/DataModels";
import * as ViewModels from "../Contracts/ViewModels";
export function replaceKnownError(err: string): string {
if (
window.dataExplorer.subscriptionType() === ViewModels.SubscriptionType.Internal &&
err.indexOf("SharedOffer is Disabled for your account") >= 0
) {
return "Database throughput is not supported for internal subscriptions.";
} else if (err.indexOf("Partition key paths must contain only valid") >= 0) {
return "Partition key paths must contain only valid characters and not contain a trailing slash or wildcard character.";
}
return err;
}
export function parse(err: any): DataModels.ErrorDataModel[] { export function parse(err: any): DataModels.ErrorDataModel[] {
try { try {

View File

@ -1,3 +1,4 @@
import { CosmosError, getErrorMessage } from "./ErrorHandlingUtils";
import { sendMessage } from "./MessageHandler"; import { sendMessage } from "./MessageHandler";
import { Diagnostics, MessageTypes } from "../Contracts/ExplorerContracts"; import { Diagnostics, MessageTypes } from "../Contracts/ExplorerContracts";
import { appInsights } from "../Shared/appInsights"; import { appInsights } from "../Shared/appInsights";
@ -21,14 +22,9 @@ export function logWarning(message: string, area: string, code?: number): void {
return _logEntry(entry); return _logEntry(entry);
} }
export function logError(message: string | Error, area: string, code?: number): void { export function logError(error: string | CosmosError | Error, area: string, code?: number): void {
let logMessage: string; const errorMessage: string = getErrorMessage(error);
if (typeof message === "string") { const entry: Diagnostics.LogEntry = _generateLogEntry(Diagnostics.LogEntryLevel.Error, errorMessage, area, code);
logMessage = message;
} else {
logMessage = JSON.stringify(message, Object.getOwnPropertyNames(message));
}
const entry: Diagnostics.LogEntry = _generateLogEntry(Diagnostics.LogEntryLevel.Error, logMessage, area, code);
return _logEntry(entry); return _logEntry(entry);
} }

View File

@ -12,6 +12,7 @@ import { BackendDefaults, HttpStatusCodes, SavedQueries } from "./Constants";
import { userContext } from "../UserContext"; import { userContext } from "../UserContext";
import { createDocument, deleteDocument, queryDocuments, queryDocumentsPage } from "./DocumentClientUtilityBase"; import { createDocument, deleteDocument, queryDocuments, queryDocumentsPage } from "./DocumentClientUtilityBase";
import { createCollection } from "./dataAccess/createCollection"; import { createCollection } from "./dataAccess/createCollection";
import { handleError } from "./ErrorHandlingUtils";
import * as ErrorParserUtility from "./ErrorParserUtility"; import * as ErrorParserUtility from "./ErrorParserUtility";
import * as Logger from "./Logger"; import * as Logger from "./Logger";
@ -53,13 +54,8 @@ export class QueriesClient {
return Promise.resolve(collection); return Promise.resolve(collection);
}, },
(error: any) => { (error: any) => {
const stringifiedError: string = error.message; handleError(error, "Failed to set up account for saving queries", "setupQueriesCollection");
NotificationConsoleUtils.logConsoleMessage( return Promise.reject(error);
ConsoleDataType.Error,
`Failed to set up account for saving queries: ${stringifiedError}`
);
Logger.logError(stringifiedError, "setupQueriesCollection");
return Promise.reject(stringifiedError);
} }
) )
.finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id)); .finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id));
@ -163,25 +159,15 @@ export class QueriesClient {
return Promise.resolve(queries); return Promise.resolve(queries);
}, },
(error: any) => { (error: any) => {
const stringifiedError: string = error.message; handleError(error, "Failed to fetch saved queries", "getSavedQueries");
NotificationConsoleUtils.logConsoleMessage( return Promise.reject(error);
ConsoleDataType.Error,
`Failed to fetch saved queries: ${stringifiedError}`
);
Logger.logError(stringifiedError, "getSavedQueries");
return Promise.reject(stringifiedError);
} }
); );
}, },
(error: any) => { (error: any) => {
// should never get into this state but we handle this regardless // should never get into this state but we handle this regardless
const stringifiedError: string = error.message; handleError(error, "Failed to fetch saved queries", "getSavedQueries");
NotificationConsoleUtils.logConsoleMessage( return Promise.reject(error);
ConsoleDataType.Error,
`Failed to fetch saved queries: ${stringifiedError}`
);
Logger.logError(stringifiedError, "getSavedQueries");
return Promise.reject(stringifiedError);
} }
) )
.finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id)); .finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id));
@ -232,13 +218,8 @@ export class QueriesClient {
return Promise.resolve(); return Promise.resolve();
}, },
(error: any) => { (error: any) => {
const stringifiedError: string = error.message; handleError(error, `Failed to delete query ${query.queryName}`, "deleteQuery");
NotificationConsoleUtils.logConsoleMessage( return Promise.reject(error);
ConsoleDataType.Error,
`Failed to delete query ${query.queryName}: ${stringifiedError}`
);
Logger.logError(stringifiedError, "deleteQuery");
return Promise.reject(stringifiedError);
} }
) )
.finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id)); .finally(() => NotificationConsoleUtils.clearInProgressMessageWithId(id));

View File

@ -7,9 +7,8 @@ import {
} from "../../Utils/arm/generatedClients/2020-04-01/types"; } from "../../Utils/arm/generatedClients/2020-04-01/types";
import { client } from "../CosmosClient"; import { client } from "../CosmosClient";
import { createUpdateSqlTrigger, getSqlTrigger } from "../../Utils/arm/generatedClients/2020-04-01/sqlResources"; import { createUpdateSqlTrigger, getSqlTrigger } from "../../Utils/arm/generatedClients/2020-04-01/sqlResources";
import { logConsoleError, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; import { handleError } from "../ErrorHandlingUtils";
import { logError } from "../Logger"; import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { sendNotificationForError } from "./sendNotificationForError";
import { userContext } from "../../UserContext"; import { userContext } from "../../UserContext";
export async function createTrigger( export async function createTrigger(
@ -66,9 +65,7 @@ export async function createTrigger(
.scripts.triggers.create(trigger); .scripts.triggers.create(trigger);
return response.resource; return response.resource;
} catch (error) { } catch (error) {
logConsoleError(`Error while creating trigger ${trigger.id}:\n ${error.message}`); handleError(error, `Error while creating trigger ${trigger.id}`, "CreateTrigger");
logError(error.message, "CreateTrigger", error.code);
sendNotificationForError(error);
throw error; throw error;
} finally { } finally {
clearMessage(); clearMessage();

View File

@ -1,7 +1,7 @@
import { Offer } from "../../Contracts/DataModels"; import { Offer } from "../../Contracts/DataModels";
import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; import { logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
import { client } from "../CosmosClient"; import { client } from "../CosmosClient";
import { handleError } from "../ErrorHandlingUtils"; import { handleError, getErrorMessage } from "../ErrorHandlingUtils";
export const readOffers = async (): Promise<Offer[]> => { export const readOffers = async (): Promise<Offer[]> => {
const clearMessage = logConsoleProgress(`Querying offers`); const clearMessage = logConsoleProgress(`Querying offers`);
@ -13,7 +13,7 @@ export const readOffers = async (): Promise<Offer[]> => {
return response?.resources; return response?.resources;
} catch (error) { } catch (error) {
// This should be removed when we can correctly identify if an account is serverless when connected using connection string too. // This should be removed when we can correctly identify if an account is serverless when connected using connection string too.
if (error.message.includes("Reading or replacing offers is not supported for serverless accounts")) { if (getErrorMessage(error)?.includes("Reading or replacing offers is not supported for serverless accounts")) {
return []; return [];
} }

View File

@ -1,20 +0,0 @@
import * as Constants from "../Constants";
import { sendMessage } from "../MessageHandler";
import { MessageTypes } from "../../Contracts/ExplorerContracts";
export interface CosmosError {
code: number;
message?: string;
}
export function sendNotificationForError(error: CosmosError): void {
if (error && error.code === Constants.HttpStatusCodes.Forbidden) {
if (error.message && error.message.toLowerCase().indexOf("sharedoffer is disabled for your account") > 0) {
return;
}
sendMessage({
type: MessageTypes.ForbiddenError,
reason: error && error.message ? error.message : error
});
}
}

View File

@ -1,8 +1,9 @@
import { Platform, configContext } from "../../ConfigContext"; import { Platform, configContext } from "../../ConfigContext";
import { getAuthorizationHeader } from "../../Utils/AuthorizationUtils"; import { getAuthorizationHeader } from "../../Utils/AuthorizationUtils";
import { AutoPilotOfferSettings } from "../../Contracts/DataModels"; import { AutoPilotOfferSettings } from "../../Contracts/DataModels";
import { logConsoleProgress, logConsoleInfo, logConsoleError } from "../../Utils/NotificationConsoleUtils"; import { logConsoleProgress, logConsoleInfo } from "../../Utils/NotificationConsoleUtils";
import { HttpHeaders } from "../Constants"; import { HttpHeaders } from "../Constants";
import { handleError } from "../ErrorHandlingUtils";
interface UpdateOfferThroughputRequest { interface UpdateOfferThroughputRequest {
subscriptionId: string; subscriptionId: string;
@ -44,8 +45,13 @@ export async function updateOfferThroughputBeyondLimit(request: UpdateOfferThrou
clearMessage(); clearMessage();
return undefined; return undefined;
} }
const error = await response.json(); const error = await response.json();
logConsoleError(`Failed to request an increase in throughput for ${request.throughput}: ${error.message}`); handleError(
error,
`Failed to request an increase in throughput for ${request.throughput}`,
"updateOfferThroughputBeyondLimit"
);
clearMessage(); clearMessage();
throw new Error(error.message); throw error;
} }

View File

@ -50,6 +50,7 @@ import {
getMongoDBCollectionIndexTransformationProgress, getMongoDBCollectionIndexTransformationProgress,
readMongoDBCollectionThroughRP readMongoDBCollectionThroughRP
} from "../../../Common/dataAccess/readMongoDBCollection"; } from "../../../Common/dataAccess/readMongoDBCollection";
import { getErrorMessage } from "../../../Common/ErrorHandlingUtils";
interface SettingsV2TabInfo { interface SettingsV2TabInfo {
tab: SettingsV2TabTypes; tab: SettingsV2TabTypes;
@ -437,7 +438,7 @@ export class SettingsComponent extends React.Component<SettingsComponentProps, S
defaultExperience: this.container.defaultExperience(), defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab, dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.props.settingsTab.tabTitle(), tabTitle: this.props.settingsTab.tabTitle(),
error: error.message error: getErrorMessage(error)
}, },
startKey startKey
); );

View File

@ -86,6 +86,7 @@ import { CommandButtonComponentProps } from "./Controls/CommandButton/CommandBut
import { updateUserContext, userContext } from "../UserContext"; import { updateUserContext, userContext } from "../UserContext";
import { stringToBlob } from "../Utils/BlobUtils"; import { stringToBlob } from "../Utils/BlobUtils";
import { IChoiceGroupProps } from "office-ui-fabric-react"; import { IChoiceGroupProps } from "office-ui-fabric-react";
import { getErrorMessage, handleError } from "../Common/ErrorHandlingUtils";
BindingHandlersRegisterer.registerBindingHandlers(); BindingHandlersRegisterer.registerBindingHandlers();
// Hold a reference to ComponentRegisterer to prevent transpiler to ignore import // Hold a reference to ComponentRegisterer to prevent transpiler to ignore import
@ -1112,7 +1113,7 @@ export default class Explorer {
); );
this.renewExplorerShareAccess(this, this.tokenForRenewal()) this.renewExplorerShareAccess(this, this.tokenForRenewal())
.fail((error: any) => { .fail((error: any) => {
const stringifiedError: string = error.message; const stringifiedError: string = getErrorMessage(error);
this.renewTokenError("Invalid connection string specified"); this.renewTokenError("Invalid connection string specified");
NotificationConsoleUtils.logConsoleMessage( NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error, ConsoleDataType.Error,
@ -1141,7 +1142,7 @@ export default class Explorer {
NotificationConsoleUtils.clearInProgressMessageWithId(id); NotificationConsoleUtils.clearInProgressMessageWithId(id);
NotificationConsoleUtils.logConsoleMessage( NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error, ConsoleDataType.Error,
`Failed to generate share url: ${error.message}` `Failed to generate share url: ${getErrorMessage(error)}`
); );
console.error(error); console.error(error);
} }
@ -1166,7 +1167,10 @@ export default class Explorer {
deferred.resolve(); deferred.resolve();
}, },
(error: any) => { (error: any) => {
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, `Failed to connect: ${error.message}`); NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error,
`Failed to connect: ${getErrorMessage(error)}`
);
deferred.reject(error); deferred.reject(error);
} }
) )
@ -1440,19 +1444,20 @@ export default class Explorer {
this._setLoadingStatusText("Failed to fetch databases."); this._setLoadingStatusText("Failed to fetch databases.");
this.isRefreshingExplorer(false); this.isRefreshingExplorer(false);
deferred.reject(error); deferred.reject(error);
const errorMessage = getErrorMessage(error);
TelemetryProcessor.traceFailure( TelemetryProcessor.traceFailure(
Action.LoadDatabases, Action.LoadDatabases,
{ {
databaseAccountName: this.databaseAccount().name, databaseAccountName: this.databaseAccount().name,
defaultExperience: this.defaultExperience(), defaultExperience: this.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree, dataExplorerArea: Constants.Areas.ResourceTree,
error: error.message error: errorMessage
}, },
startKey startKey
); );
NotificationConsoleUtils.logConsoleMessage( NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error, ConsoleDataType.Error,
`Error while refreshing databases: ${error.message}` `Error while refreshing databases: ${errorMessage}`
); );
} }
); );
@ -1554,8 +1559,7 @@ export default class Explorer {
return Promise.all(sparkPromises).then(() => workspaceItems); return Promise.all(sparkPromises).then(() => workspaceItems);
} catch (error) { } catch (error) {
Logger.logError(error, "Explorer/this._arcadiaManager.listWorkspacesAsync"); handleError(error, "Get Arcadia workspaces failed", "Explorer/this._arcadiaManager.listWorkspacesAsync");
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, error.message);
return Promise.resolve([]); return Promise.resolve([]);
} }
} }
@ -1590,10 +1594,10 @@ export default class Explorer {
); );
} catch (error) { } catch (error) {
this._isInitializingNotebooks = false; this._isInitializingNotebooks = false;
Logger.logError(error, "initNotebooks/getNotebookConnectionInfoAsync"); handleError(
NotificationConsoleUtils.logConsoleMessage( error,
ConsoleDataType.Error, `Failed to get notebook workspace connection info: ${getErrorMessage(error)}`,
`Failed to get notebook workspace connection info: ${error.message}` "initNotebooks/getNotebookConnectionInfoAsync"
); );
throw error; throw error;
} finally { } finally {
@ -1669,8 +1673,7 @@ export default class Explorer {
await this.notebookWorkspaceManager.startNotebookWorkspaceAsync(this.databaseAccount().id, "default"); await this.notebookWorkspaceManager.startNotebookWorkspaceAsync(this.databaseAccount().id, "default");
} }
} catch (error) { } catch (error) {
Logger.logError(error, "Explorer/ensureNotebookWorkspaceRunning"); handleError(error, "Failed to initialize notebook workspace", "Explorer/ensureNotebookWorkspaceRunning");
NotificationConsoleUtils.logConsoleError(`Failed to initialize notebook workspace: ${error.message}`);
} finally { } finally {
clearMessage && clearMessage(); clearMessage && clearMessage();
} }
@ -2052,7 +2055,7 @@ export default class Explorer {
databaseAccountName: this.databaseAccount() && this.databaseAccount().name, databaseAccountName: this.databaseAccount() && this.databaseAccount().name,
defaultExperience: this.defaultExperience && this.defaultExperience(), defaultExperience: this.defaultExperience && this.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree, dataExplorerArea: Constants.Areas.ResourceTree,
trace: error.message trace: getErrorMessage(error)
}, },
startKey startKey
); );
@ -2514,7 +2517,7 @@ export default class Explorer {
(error: any) => { (error: any) => {
NotificationConsoleUtils.logConsoleMessage( NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error, ConsoleDataType.Error,
`Could not download notebook ${error.message}` `Could not download notebook ${getErrorMessage(error)}`
); );
clearMessage(); clearMessage();

View File

@ -29,6 +29,7 @@ import { InputProperty } from "../../../Contracts/ViewModels";
import { QueryIterator, ItemDefinition, Resource } from "@azure/cosmos"; import { QueryIterator, ItemDefinition, Resource } from "@azure/cosmos";
import LoadingIndicatorIcon from "../../../../images/LoadingIndicator_3Squares.gif"; import LoadingIndicatorIcon from "../../../../images/LoadingIndicator_3Squares.gif";
import { queryDocuments, queryDocumentsPage } from "../../../Common/DocumentClientUtilityBase"; import { queryDocuments, queryDocumentsPage } from "../../../Common/DocumentClientUtilityBase";
import { getErrorMessage } from "../../../Common/ErrorHandlingUtils";
export interface GraphAccessor { export interface GraphAccessor {
applyFilter: () => void; applyFilter: () => void;
@ -892,7 +893,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
backendPromise.then( backendPromise.then(
(result: UserQueryResult) => (this.queryTotalRequestCharge = result.requestCharge), (result: UserQueryResult) => (this.queryTotalRequestCharge = result.requestCharge),
(error: any) => { (error: any) => {
const errorMsg = `Failure in submitting query: ${query}: ${error.message}`; const errorMsg = `Failure in submitting query: ${query}: ${getErrorMessage(error)}`;
GraphExplorer.reportToConsole(ConsoleDataType.Error, errorMsg); GraphExplorer.reportToConsole(ConsoleDataType.Error, errorMsg);
this.setState({ this.setState({
filterQueryError: errorMsg filterQueryError: errorMsg
@ -1826,7 +1827,7 @@ export class GraphExplorer extends React.Component<GraphExplorerProps, GraphExpl
promise promise
.then((result: GremlinClient.GremlinRequestResult) => this.processGremlinQueryResults(result)) .then((result: GremlinClient.GremlinRequestResult) => this.processGremlinQueryResults(result))
.catch((error: any) => { .catch((error: any) => {
const errorMsg = `Failed to process query result: ${error.message}`; const errorMsg = `Failed to process query result: ${getErrorMessage(error)}`;
GraphExplorer.reportToConsole(ConsoleDataType.Error, errorMsg); GraphExplorer.reportToConsole(ConsoleDataType.Error, errorMsg);
this.setState({ this.setState({
filterQueryError: errorMsg filterQueryError: errorMsg

View File

@ -8,6 +8,7 @@ import * as NotificationConsoleUtils from "../../../Utils/NotificationConsoleUti
import { ConsoleDataType } from "../../Menus/NotificationConsole/NotificationConsoleComponent"; import { ConsoleDataType } from "../../Menus/NotificationConsole/NotificationConsoleComponent";
import { HashMap } from "../../../Common/HashMap"; import { HashMap } from "../../../Common/HashMap";
import * as Logger from "../../../Common/Logger"; import * as Logger from "../../../Common/Logger";
import { getErrorMessage } from "../../../Common/ErrorHandlingUtils";
export interface GremlinClientParameters { export interface GremlinClientParameters {
endpoint: string; endpoint: string;
@ -58,14 +59,11 @@ export class GremlinClient {
} }
}, },
failureCallback: (result: Result, error: any) => { failureCallback: (result: Result, error: any) => {
if (typeof error !== "string") { const errorMessage = getErrorMessage(error);
error = error.message;
}
const requestId = result.requestId; const requestId = result.requestId;
if (!requestId || !this.pendingResults.has(requestId)) { if (!requestId || !this.pendingResults.has(requestId)) {
const msg = `Error: ${error}, unknown requestId:${requestId} ${GremlinClient.getRequestChargeString( const msg = `Error: ${errorMessage}, unknown requestId:${requestId} ${GremlinClient.getRequestChargeString(
result.requestCharge result.requestCharge
)}`; )}`;
GremlinClient.reportError(msg); GremlinClient.reportError(msg);
@ -73,11 +71,11 @@ export class GremlinClient {
// Fail all pending requests if no request id (fatal) // Fail all pending requests if no request id (fatal)
if (!requestId) { if (!requestId) {
this.pendingResults.keys().forEach((reqId: string) => { this.pendingResults.keys().forEach((reqId: string) => {
this.abortPendingRequest(reqId, error, null); this.abortPendingRequest(reqId, errorMessage, null);
}); });
} }
} else { } else {
this.abortPendingRequest(requestId, error, result.requestCharge); this.abortPendingRequest(requestId, errorMessage, result.requestCharge);
} }
}, },
infoCallback: (msg: string) => { infoCallback: (msg: string) => {

View File

@ -15,6 +15,7 @@ import { configContext, Platform } from "../../ConfigContext";
import { ContextualPaneBase } from "./ContextualPaneBase"; import { ContextualPaneBase } from "./ContextualPaneBase";
import { DynamicListItem } from "../Controls/DynamicList/DynamicListComponent"; import { DynamicListItem } from "../Controls/DynamicList/DynamicListComponent";
import { createCollection } from "../../Common/dataAccess/createCollection"; import { createCollection } from "../../Common/dataAccess/createCollection";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
export interface AddCollectionPaneOptions extends ViewModels.PaneOptions { export interface AddCollectionPaneOptions extends ViewModels.PaneOptions {
isPreferredApiTable: ko.Computed<boolean>; isPreferredApiTable: ko.Computed<boolean>;
@ -881,10 +882,9 @@ export default class AddCollectionPane extends ContextualPaneBase {
this.resetData(); this.resetData();
this.container.refreshAllDatabases(); this.container.refreshAllDatabases();
}, },
(reason: any) => { (error: any) => {
this.isExecuting(false); this.isExecuting(false);
const message = ErrorParserUtility.parse(reason); const errorMessage: string = getErrorMessage(error);
const errorMessage = ErrorParserUtility.replaceKnownError(message[0].message);
this.formErrors(errorMessage); this.formErrors(errorMessage);
this.formErrorsDetails(errorMessage); this.formErrorsDetails(errorMessage);
const addCollectionPaneFailedMessage = { const addCollectionPaneFailedMessage = {
@ -912,7 +912,7 @@ export default class AddCollectionPane extends ContextualPaneBase {
flight: this.container.flight() flight: this.container.flight()
}, },
dataExplorerArea: Constants.Areas.ContextualPane, dataExplorerArea: Constants.Areas.ContextualPane,
error: reason error: errorMessage
}; };
TelemetryProcessor.traceFailure(Action.CreateCollection, addCollectionPaneFailedMessage, startKey); TelemetryProcessor.traceFailure(Action.CreateCollection, addCollectionPaneFailedMessage, startKey);
} }

View File

@ -7,6 +7,7 @@ import * as Logger from "../../Common/Logger";
import { QueriesGridComponentAdapter } from "../Controls/QueriesGridReactComponent/QueriesGridComponentAdapter"; import { QueriesGridComponentAdapter } from "../Controls/QueriesGridReactComponent/QueriesGridComponentAdapter";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import QueryTab from "../Tabs/QueryTab"; import QueryTab from "../Tabs/QueryTab";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
export class BrowseQueriesPane extends ContextualPaneBase { export class BrowseQueriesPane extends ContextualPaneBase {
public queriesGridComponentAdapter: QueriesGridComponentAdapter; public queriesGridComponentAdapter: QueriesGridComponentAdapter;
@ -60,17 +61,19 @@ export class BrowseQueriesPane extends ContextualPaneBase {
startKey startKey
); );
} catch (error) { } catch (error) {
const errorMessage = getErrorMessage(error);
TelemetryProcessor.traceFailure( TelemetryProcessor.traceFailure(
Action.SetupSavedQueries, Action.SetupSavedQueries,
{ {
databaseAccountName: this.container && this.container.databaseAccount().name, databaseAccountName: this.container && this.container.databaseAccount().name,
defaultExperience: this.container && this.container.defaultExperience(), defaultExperience: this.container && this.container.defaultExperience(),
dataExplorerArea: Areas.ContextualPane, dataExplorerArea: Areas.ContextualPane,
paneTitle: this.title() paneTitle: this.title(),
error: errorMessage
}, },
startKey startKey
); );
this.formErrors(`Failed to setup a collection for saved queries: ${error.message}`); this.formErrors(`Failed to setup a collection for saved queries: ${errorMessage}`);
} finally { } finally {
this.isExecuting(false); this.isExecuting(false);
} }

View File

@ -7,6 +7,7 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent"; import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsoleComponent";
import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility"; import { DefaultExperienceUtility } from "../../Shared/DefaultExperienceUtility";
import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils"; import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
export class RenewAdHocAccessPane extends ContextualPaneBase { export class RenewAdHocAccessPane extends ContextualPaneBase {
public accessKey: ko.Observable<string>; public accessKey: ko.Observable<string>;
@ -82,7 +83,7 @@ export class RenewAdHocAccessPane extends ContextualPaneBase {
this.container this.container
.renewShareAccess(this.accessKey()) .renewShareAccess(this.accessKey())
.fail((error: any) => { .fail((error: any) => {
const errorMessage: string = error.message; const errorMessage: string = getErrorMessage(error);
NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, `Failed to connect: ${errorMessage}`); NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, `Failed to connect: ${errorMessage}`);
this.formErrors(errorMessage); this.formErrors(errorMessage);
this.formErrorsDetails(errorMessage); this.formErrorsDetails(errorMessage);

View File

@ -8,6 +8,7 @@ import { ConsoleDataType } from "../Menus/NotificationConsole/NotificationConsol
import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils"; import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import QueryTab from "../Tabs/QueryTab"; import QueryTab from "../Tabs/QueryTab";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
export class SaveQueryPane extends ContextualPaneBase { export class SaveQueryPane extends ContextualPaneBase {
public queryName: ko.Observable<string>; public queryName: ko.Observable<string>;
@ -87,18 +88,17 @@ export class SaveQueryPane extends ContextualPaneBase {
}, },
(error: any) => { (error: any) => {
this.isExecuting(false); this.isExecuting(false);
if (typeof error != "string") { const errorMessage = getErrorMessage(error);
error = error.message;
}
this.formErrors("Failed to save query"); this.formErrors("Failed to save query");
this.formErrorsDetails(`Failed to save query: ${error}`); this.formErrorsDetails(`Failed to save query: ${errorMessage}`);
TelemetryProcessor.traceFailure( TelemetryProcessor.traceFailure(
Action.SaveQuery, Action.SaveQuery,
{ {
databaseAccountName: this.container.databaseAccount().name, databaseAccountName: this.container.databaseAccount().name,
defaultExperience: this.container.defaultExperience(), defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.ContextualPane, dataExplorerArea: Constants.Areas.ContextualPane,
paneTitle: this.title() paneTitle: this.title(),
error: errorMessage
}, },
startKey startKey
); );
@ -132,18 +132,20 @@ export class SaveQueryPane extends ContextualPaneBase {
startKey startKey
); );
} catch (error) { } catch (error) {
const errorMessage = getErrorMessage(error);
TelemetryProcessor.traceFailure( TelemetryProcessor.traceFailure(
Action.SetupSavedQueries, Action.SetupSavedQueries,
{ {
databaseAccountName: this.container && this.container.databaseAccount().name, databaseAccountName: this.container && this.container.databaseAccount().name,
defaultExperience: this.container && this.container.defaultExperience(), defaultExperience: this.container && this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.ContextualPane, dataExplorerArea: Constants.Areas.ContextualPane,
paneTitle: this.title() paneTitle: this.title(),
error: errorMessage
}, },
startKey startKey
); );
this.formErrors("Failed to setup a container for saved queries"); this.formErrors("Failed to setup a container for saved queries");
this.formErrors(`Failed to setup a container for saved queries: ${error.message}`); this.formErrorsDetails(`Failed to setup a container for saved queries: ${errorMessage}`);
} finally { } finally {
this.isExecuting(false); this.isExecuting(false);
} }

View File

@ -6,6 +6,7 @@ import { ContextualPaneBase } from "./ContextualPaneBase";
import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils"; import * as NotificationConsoleUtils from "../../Utils/NotificationConsoleUtils";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor"; import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import * as ko from "knockout"; import * as ko from "knockout";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
export class SetupNotebooksPane extends ContextualPaneBase { export class SetupNotebooksPane extends ContextualPaneBase {
private description: ko.Observable<string>; private description: ko.Observable<string>;
@ -85,7 +86,7 @@ export class SetupNotebooksPane extends ContextualPaneBase {
"Successfully created a default notebook workspace for the account" "Successfully created a default notebook workspace for the account"
); );
} catch (error) { } catch (error) {
const errorMessage = typeof error == "string" ? error : error.message; const errorMessage = getErrorMessage(error);
TelemetryProcessor.traceFailure( TelemetryProcessor.traceFailure(
Action.CreateNotebookWorkspace, Action.CreateNotebookWorkspace,
{ {

View File

@ -32,6 +32,7 @@ import {
createDocument createDocument
} from "../../Common/DocumentClientUtilityBase"; } from "../../Common/DocumentClientUtilityBase";
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent"; import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
export default class DocumentsTab extends TabsBase { export default class DocumentsTab extends TabsBase {
public selectedDocumentId: ko.Observable<DocumentId>; public selectedDocumentId: ko.Observable<DocumentId>;
@ -774,10 +775,8 @@ export default class DocumentsTab extends TabsBase {
}, },
error => { error => {
this.isExecutionError(true); this.isExecutionError(true);
NotificationConsoleUtils.logConsoleMessage( const errorMessage = getErrorMessage(error);
ConsoleDataType.Error, NotificationConsoleUtils.logConsoleMessage(ConsoleDataType.Error, errorMessage);
typeof error === "string" ? error : error.message
);
if (this.onLoadStartKey != null && this.onLoadStartKey != undefined) { if (this.onLoadStartKey != null && this.onLoadStartKey != undefined) {
TelemetryProcessor.traceFailure( TelemetryProcessor.traceFailure(
Action.Tab, Action.Tab,
@ -788,7 +787,7 @@ export default class DocumentsTab extends TabsBase {
defaultExperience: this.collection.container.defaultExperience(), defaultExperience: this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab, dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle(), tabTitle: this.tabTitle(),
error: error error: errorMessage
}, },
this.onLoadStartKey this.onLoadStartKey
); );

View File

@ -22,6 +22,7 @@ import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandBu
import { userContext } from "../../UserContext"; import { userContext } from "../../UserContext";
import { updateOfferThroughputBeyondLimit } from "../../Common/dataAccess/updateOfferThroughputBeyondLimit"; import { updateOfferThroughputBeyondLimit } from "../../Common/dataAccess/updateOfferThroughputBeyondLimit";
import { configContext, Platform } from "../../ConfigContext"; import { configContext, Platform } from "../../ConfigContext";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
const ttlWarning: string = ` const ttlWarning: string = `
The system will automatically delete items based on the TTL value (in seconds) you provide, without needing a delete operation explicitly issued by a client application. The system will automatically delete items based on the TTL value (in seconds) you provide, without needing a delete operation explicitly issued by a client application.
@ -1174,7 +1175,7 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
defaultExperience: this.container.defaultExperience(), defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab, dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle(), tabTitle: this.tabTitle(),
error: error.message error: getErrorMessage(error)
}, },
startKey startKey
); );

View File

@ -40,6 +40,7 @@ import Explorer from "../Explorer";
import { userContext } from "../../UserContext"; import { userContext } from "../../UserContext";
import TabsBase from "../Tabs/TabsBase"; import TabsBase from "../Tabs/TabsBase";
import { fetchPortalNotifications } from "../../Common/PortalNotifications"; import { fetchPortalNotifications } from "../../Common/PortalNotifications";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
export default class Collection implements ViewModels.Collection { export default class Collection implements ViewModels.Collection {
public nodeKind: string; public nodeKind: string;
@ -610,6 +611,7 @@ export default class Collection implements ViewModels.Collection {
settingsTab.pendingNotification(pendingNotification); settingsTab.pendingNotification(pendingNotification);
}, },
(error: any) => { (error: any) => {
const errorMessage = getErrorMessage(error);
TelemetryProcessor.traceFailure( TelemetryProcessor.traceFailure(
Action.Tab, Action.Tab,
{ {
@ -619,13 +621,13 @@ export default class Collection implements ViewModels.Collection {
defaultExperience: this.container.defaultExperience(), defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab, dataExplorerArea: Constants.Areas.Tab,
tabTitle: settingsTabOptions.title, tabTitle: settingsTabOptions.title,
error: error error: errorMessage
}, },
startKey startKey
); );
NotificationConsoleUtils.logConsoleMessage( NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error, ConsoleDataType.Error,
`Error while fetching container settings for container ${this.id()}: ${error.message}` `Error while fetching container settings for container ${this.id()}: ${errorMessage}`
); );
throw error; throw error;
} }
@ -869,7 +871,7 @@ export default class Collection implements ViewModels.Collection {
collectionName: this.id(), collectionName: this.id(),
defaultExperience: this.container.defaultExperience(), defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree, dataExplorerArea: Constants.Areas.ResourceTree,
error: typeof error === "string" ? error : error.message error: getErrorMessage(error)
}); });
} }
); );
@ -928,7 +930,7 @@ export default class Collection implements ViewModels.Collection {
collectionName: this.id(), collectionName: this.id(),
defaultExperience: this.container.defaultExperience(), defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree, dataExplorerArea: Constants.Areas.ResourceTree,
error: typeof error === "string" ? error : error.message error: getErrorMessage(error)
}); });
} }
); );
@ -988,7 +990,7 @@ export default class Collection implements ViewModels.Collection {
collectionName: this.id(), collectionName: this.id(),
defaultExperience: this.container.defaultExperience(), defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.ResourceTree, dataExplorerArea: Constants.Areas.ResourceTree,
error: typeof error === "string" ? error : error.message error: getErrorMessage(error)
}); });
} }
); );
@ -1185,7 +1187,7 @@ export default class Collection implements ViewModels.Collection {
}, },
error => { error => {
record.numFailed++; record.numFailed++;
record.errors = [...record.errors, error.message]; record.errors = [...record.errors, getErrorMessage(error)];
return Q.resolve(); return Q.resolve();
} }
); );
@ -1238,7 +1240,7 @@ export default class Collection implements ViewModels.Collection {
(error: any) => { (error: any) => {
Logger.logError( Logger.logError(
JSON.stringify({ JSON.stringify({
error: error.message, error: getErrorMessage(error),
accountName: this.container && this.container.databaseAccount(), accountName: this.container && this.container.databaseAccount(),
databaseName: this.databaseId, databaseName: this.databaseId,
collectionName: this.id() collectionName: this.id()

View File

@ -16,6 +16,7 @@ import { readCollections } from "../../Common/dataAccess/readCollections";
import { readDatabaseOffer } from "../../Common/dataAccess/readDatabaseOffer"; import { readDatabaseOffer } from "../../Common/dataAccess/readDatabaseOffer";
import { DefaultAccountExperienceType } from "../../DefaultAccountExperienceType"; import { DefaultAccountExperienceType } from "../../DefaultAccountExperienceType";
import { fetchPortalNotifications } from "../../Common/PortalNotifications"; import { fetchPortalNotifications } from "../../Common/PortalNotifications";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
export default class Database implements ViewModels.Database { export default class Database implements ViewModels.Database {
public nodeKind: string; public nodeKind: string;
@ -88,6 +89,7 @@ export default class Database implements ViewModels.Database {
this.container.tabsManager.activateNewTab(settingsTab); this.container.tabsManager.activateNewTab(settingsTab);
}, },
(error: any) => { (error: any) => {
const errorMessage = getErrorMessage(error);
TelemetryProcessor.traceFailure( TelemetryProcessor.traceFailure(
Action.Tab, Action.Tab,
{ {
@ -97,13 +99,13 @@ export default class Database implements ViewModels.Database {
defaultExperience: this.container.defaultExperience(), defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab, dataExplorerArea: Constants.Areas.Tab,
tabTitle: "Scale", tabTitle: "Scale",
error: error error: errorMessage
}, },
startKey startKey
); );
NotificationConsoleUtils.logConsoleMessage( NotificationConsoleUtils.logConsoleMessage(
ConsoleDataType.Error, ConsoleDataType.Error,
`Error while fetching database settings for database ${this.id()}: ${error.message}` `Error while fetching database settings for database ${this.id()}: ${errorMessage}`
); );
throw error; throw error;
} }
@ -239,7 +241,7 @@ export default class Database implements ViewModels.Database {
(error: any) => { (error: any) => {
Logger.logError( Logger.logError(
JSON.stringify({ JSON.stringify({
error: error.message, error: getErrorMessage(error),
accountName: this.container && this.container.databaseAccount(), accountName: this.container && this.container.databaseAccount(),
databaseName: this.id(), databaseName: this.id(),
collectionName: this.id() collectionName: this.id()

View File

@ -9,6 +9,7 @@ import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import Explorer from "../Explorer"; import Explorer from "../Explorer";
import StoredProcedureTab from "../Tabs/StoredProcedureTab"; import StoredProcedureTab from "../Tabs/StoredProcedureTab";
import TabsBase from "../Tabs/TabsBase"; import TabsBase from "../Tabs/TabsBase";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
const sampleStoredProcedureBody: string = `// SAMPLE STORED PROCEDURE const sampleStoredProcedureBody: string = `// SAMPLE STORED PROCEDURE
function sample(prefix) { function sample(prefix) {
@ -158,7 +159,7 @@ export default class StoredProcedure {
sprocTab.onExecuteSprocsResult(result, result.scriptLogs); sprocTab.onExecuteSprocsResult(result, result.scriptLogs);
}, },
(error: any) => { (error: any) => {
sprocTab.onExecuteSprocsError(error.message); sprocTab.onExecuteSprocsError(getErrorMessage(error));
} }
) )
.finally(() => { .finally(() => {

View File

@ -9,6 +9,7 @@ import { NotebookUtil } from "../Explorer/Notebook/NotebookUtil";
import { GitHubClient, IGitHubFile, IGitHubResponse } from "./GitHubClient"; import { GitHubClient, IGitHubFile, IGitHubResponse } from "./GitHubClient";
import * as GitHubUtils from "../Utils/GitHubUtils"; import * as GitHubUtils from "../Utils/GitHubUtils";
import UrlUtility from "../Common/UrlUtility"; import UrlUtility from "../Common/UrlUtility";
import { getErrorMessage } from "../Common/ErrorHandlingUtils";
export interface GitHubContentProviderParams { export interface GitHubContentProviderParams {
gitHubClient: GitHubClient; gitHubClient: GitHubClient;
@ -423,7 +424,7 @@ export class GitHubContentProvider implements IContentProvider {
request: {}, request: {},
status: error.errno, status: error.errno,
response: error, response: error,
responseText: error.message, responseText: getErrorMessage(error),
responseType: "json" responseType: "json"
}; };
} }

View File

@ -21,6 +21,7 @@ import {
import { DialogComponentAdapter } from "./Explorer/Controls/DialogReactComponent/DialogComponentAdapter"; import { DialogComponentAdapter } from "./Explorer/Controls/DialogReactComponent/DialogComponentAdapter";
import { DialogProps } from "./Explorer/Controls/DialogReactComponent/DialogComponent"; import { DialogProps } from "./Explorer/Controls/DialogReactComponent/DialogComponent";
import { DirectoryListProps } from "./Explorer/Controls/Directory/DirectoryListComponent"; import { DirectoryListProps } from "./Explorer/Controls/Directory/DirectoryListComponent";
import { getErrorMessage } from "./Common/ErrorHandlingUtils";
import { initializeIcons } from "office-ui-fabric-react/lib/Icons"; import { initializeIcons } from "office-ui-fabric-react/lib/Icons";
import { LocalStorageUtility, StorageKey, SessionStorageUtility } from "./Shared/StorageUtility"; import { LocalStorageUtility, StorageKey, SessionStorageUtility } from "./Shared/StorageUtility";
import * as Logger from "./Common/Logger"; import * as Logger from "./Common/Logger";
@ -509,12 +510,13 @@ class HostedExplorer {
} }
}); });
} catch (error) { } catch (error) {
Logger.logError(error, "HostedExplorer/_getArcadiaToken"); const errorMessage = getErrorMessage(error);
Logger.logError(errorMessage, "HostedExplorer/_getArcadiaToken");
this._sendMessageToExplorerFrame({ this._sendMessageToExplorerFrame({
actionType: ActionType.TransmitCachedData, actionType: ActionType.TransmitCachedData,
message: { message: {
id: message && message.id, id: message && message.id,
error: error.message error: errorMessage
} }
}); });
} }
@ -559,12 +561,9 @@ class HostedExplorer {
}); });
}, },
error => { error => {
if (typeof error !== "string") {
error = JSON.stringify(error, Object.getOwnPropertyNames(error));
}
this._sendMessageToExplorerFrame({ this._sendMessageToExplorerFrame({
type: MessageTypes.GetAccessAadResponse, type: MessageTypes.GetAccessAadResponse,
error error: getErrorMessage(error)
}); });
} }
); );
@ -1008,7 +1007,7 @@ class HostedExplorer {
return accounts; return accounts;
} catch (error) { } catch (error) {
this._logConsoleMessage(ConsoleDataType.Error, `Failed to fetch accounts: ${error.message}`); this._logConsoleMessage(ConsoleDataType.Error, `Failed to fetch accounts: ${getErrorMessage(error)}`);
this._clearInProgressMessageWithId(id); this._clearInProgressMessageWithId(id);
throw error; throw error;
@ -1047,7 +1046,7 @@ class HostedExplorer {
displayText: "Error loading account" displayText: "Error loading account"
}); });
this._updateLoadingStatusText(`Failed to load selected account: ${newAccount.name}`); this._updateLoadingStatusText(`Failed to load selected account: ${newAccount.name}`);
this._logConsoleMessage(ConsoleDataType.Error, `Failed to connect: ${error.message}`); this._logConsoleMessage(ConsoleDataType.Error, `Failed to connect: ${getErrorMessage(error)}`);
this._clearInProgressMessageWithId(id); this._clearInProgressMessageWithId(id);
throw error; throw error;
} }

View File

@ -23,6 +23,7 @@ import "../../Explorer/Tables/DataTable/DataTableBindingManager";
import Explorer from "../../Explorer/Explorer"; import Explorer from "../../Explorer/Explorer";
import { updateUserContext } from "../../UserContext"; import { updateUserContext } from "../../UserContext";
import { configContext } from "../../ConfigContext"; import { configContext } from "../../ConfigContext";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
export default class Main { export default class Main {
private static _databaseAccountId: string; private static _databaseAccountId: string;
@ -245,7 +246,7 @@ export default class Main {
); );
}, },
(error: any) => { (error: any) => {
deferred.reject(`Failed to generate encrypted token: ${error.message}`); deferred.reject(`Failed to generate encrypted token: ${getErrorMessage(error)}`);
} }
); );

View File

@ -3,6 +3,7 @@ import { DocumentClientParams, UploadDetailsRecord, UploadDetails } from "./defi
import { client } from "../../Common/CosmosClient"; import { client } from "../../Common/CosmosClient";
import { configContext, updateConfigContext } from "../../ConfigContext"; import { configContext, updateConfigContext } from "../../ConfigContext";
import { updateUserContext } from "../../UserContext"; import { updateUserContext } from "../../UserContext";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
let numUploadsSuccessful = 0; let numUploadsSuccessful = 0;
let numUploadsFailed = 0; let numUploadsFailed = 0;
@ -93,7 +94,7 @@ function createDocumentsFromFile(fileName: string, documentContent: string): voi
}) })
.catch(error => { .catch(error => {
console.error(error); console.error(error);
recordUploadDetailErrorForFile(fileName, error.message); recordUploadDetailErrorForFile(fileName, getErrorMessage(error));
numUploadsFailed++; numUploadsFailed++;
}) })
.finally(() => { .finally(() => {

View File

@ -15,13 +15,11 @@
"./src/Common/DeleteFeedback.ts", "./src/Common/DeleteFeedback.ts",
"./src/Common/HashMap.ts", "./src/Common/HashMap.ts",
"./src/Common/HeadersUtility.ts", "./src/Common/HeadersUtility.ts",
"./src/Common/Logger.ts",
"./src/Common/MessageHandler.ts", "./src/Common/MessageHandler.ts",
"./src/Common/MongoUtility.ts", "./src/Common/MongoUtility.ts",
"./src/Common/ObjectCache.ts", "./src/Common/ObjectCache.ts",
"./src/Common/ThemeUtility.ts", "./src/Common/ThemeUtility.ts",
"./src/Common/UrlUtility.ts", "./src/Common/UrlUtility.ts",
"./src/Common/dataAccess/sendNotificationForError.ts",
"./src/ConfigContext.ts", "./src/ConfigContext.ts",
"./src/Contracts/ActionContracts.ts", "./src/Contracts/ActionContracts.ts",
"./src/Contracts/DataModels.ts", "./src/Contracts/DataModels.ts",