Refactor error handling in data explorer Part 3 (#315)

- Make sure we pass the error message string instead of an error object when we call `TelemetryProcessor.traceFailure` since TelemetryProcessor will call `JSON.stringify` on the error object which would result in an empty object
- Removed ErrorParserUtility since it only works on specific error types. We can just log the full error message and manually derive information we need from the message.
- Added option to include stack trace in `getErrorMessage`. This is useful for figuring out where the client side script errors are coming from.
- Some minor refactors
This commit is contained in:
victor-meng
2020-11-05 20:02:57 -08:00
committed by GitHub
parent 53a8cea95e
commit 79dec6a8a8
33 changed files with 218 additions and 267 deletions

View File

@@ -6,7 +6,6 @@ import * as ViewModels from "../../Contracts/ViewModels";
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
import { AccessibleVerticalList } from "../Tree/AccessibleVerticalList";
import { KeyCodes } from "../../Common/Constants";
import * as ErrorParserUtility from "../../Common/ErrorParserUtility";
import ConflictId from "../Tree/ConflictId";
import editable from "../../Common/EditableUtility";
import * as HeadersUtility from "../../Common/HeadersUtility";
@@ -28,6 +27,7 @@ import {
updateDocument
} from "../../Common/DocumentClientUtilityBase";
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
export default class ConflictsTab extends TabsBase {
public selectedConflictId: ko.Observable<ConflictId>;
@@ -241,9 +241,8 @@ export default class ConflictsTab extends TabsBase {
return this.loadNextPage();
}
)
.catch(reason => {
const message = ErrorParserUtility.parse(reason)[0].message;
window.alert(message);
.catch(error => {
window.alert(getErrorMessage(error));
});
}
@@ -336,10 +335,10 @@ export default class ConflictsTab extends TabsBase {
);
});
},
reason => {
error => {
this.isExecutionError(true);
const message = ErrorParserUtility.parse(reason)[0].message;
window.alert(message);
const errorMessage = getErrorMessage(error);
window.alert(errorMessage);
TelemetryProcessor.traceFailure(
Action.ResolveConflict,
{
@@ -349,7 +348,9 @@ export default class ConflictsTab extends TabsBase {
tabTitle: this.tabTitle(),
conflictResourceType: selectedConflict.resourceType,
conflictOperationType: selectedConflict.operationType,
conflictResourceId: selectedConflict.resourceId
conflictResourceId: selectedConflict.resourceId,
error: errorMessage,
errorStack: getErrorStack(error)
},
startKey
);
@@ -396,10 +397,10 @@ export default class ConflictsTab extends TabsBase {
startKey
);
},
reason => {
error => {
this.isExecutionError(true);
const message = ErrorParserUtility.parse(reason)[0].message;
window.alert(message);
const errorMessage = getErrorMessage(error);
window.alert(errorMessage);
TelemetryProcessor.traceFailure(
Action.DeleteConflict,
{
@@ -409,7 +410,9 @@ export default class ConflictsTab extends TabsBase {
tabTitle: this.tabTitle(),
conflictResourceType: selectedConflict.resourceType,
conflictOperationType: selectedConflict.operationType,
conflictResourceId: selectedConflict.resourceId
conflictResourceId: selectedConflict.resourceId,
error: errorMessage,
errorStack: getErrorStack(error)
},
startKey
);
@@ -470,7 +473,8 @@ export default class ConflictsTab extends TabsBase {
defaultExperience: this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle(),
error: error
error: getErrorMessage(error),
errorStack: getErrorStack(error)
},
this.onLoadStartKey
);
@@ -545,7 +549,8 @@ export default class ConflictsTab extends TabsBase {
defaultExperience: this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle(),
error: error
error: getErrorMessage(error),
errorStack: getErrorStack(error)
},
this.onLoadStartKey
);

View File

@@ -1,7 +1,6 @@
import * as AutoPilotUtils from "../../Utils/AutoPilotUtils";
import * as Constants from "../../Common/Constants";
import * as DataModels from "../../Contracts/DataModels";
import * as ErrorParserUtility from "../../Common/ErrorParserUtility";
import * as ko from "knockout";
import * as PricingUtils from "../../Utils/PricingUtils";
import * as SharedConstants from "../../Shared/Constants";
@@ -20,6 +19,7 @@ import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandBu
import { userContext } from "../../UserContext";
import { updateOfferThroughputBeyondLimit } from "../../Common/dataAccess/updateOfferThroughputBeyondLimit";
import { configContext, Platform } from "../../ConfigContext";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
const updateThroughputBeyondLimitWarningMessage: string = `
You are about to request an increase in throughput beyond the pre-allocated capacity.
@@ -490,7 +490,8 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
this.container.isRefreshingExplorer(false);
this.isExecutionError(true);
console.error(error);
this.displayedError(ErrorParserUtility.parse(error)[0].message);
const errorMessage = getErrorMessage(error);
this.displayedError(errorMessage);
TelemetryProcessor.traceFailure(
Action.UpdateSettings,
{
@@ -499,7 +500,8 @@ export default class DatabaseSettingsTab extends TabsBase implements ViewModels.
defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle(),
error: error
error: errorMessage,
errorStack: getErrorStack(error)
},
startKey
);

View File

@@ -6,7 +6,6 @@ import * as ViewModels from "../../Contracts/ViewModels";
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
import { AccessibleVerticalList } from "../Tree/AccessibleVerticalList";
import { KeyCodes } from "../../Common/Constants";
import * as ErrorParserUtility from "../../Common/ErrorParserUtility";
import DocumentId from "../Tree/DocumentId";
import editable from "../../Common/EditableUtility";
import * as HeadersUtility from "../../Common/HeadersUtility";
@@ -32,7 +31,7 @@ import {
createDocument
} from "../../Common/DocumentClientUtilityBase";
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
export default class DocumentsTab extends TabsBase {
public selectedDocumentId: ko.Observable<DocumentId>;
@@ -393,9 +392,8 @@ export default class DocumentsTab extends TabsBase {
const focusElement = document.getElementById("errorStatusIcon");
focusElement && focusElement.focus();
})
.catch(reason => {
const message = ErrorParserUtility.parse(reason)[0].message;
window.alert(message);
.catch(error => {
window.alert(getErrorMessage(error));
});
}
@@ -475,17 +473,19 @@ export default class DocumentsTab extends TabsBase {
startKey
);
},
reason => {
error => {
this.isExecutionError(true);
const message = ErrorParserUtility.parse(reason)[0].message;
window.alert(message);
const errorMessage = getErrorMessage(error);
window.alert(errorMessage);
TelemetryProcessor.traceFailure(
Action.CreateDocument,
{
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: errorMessage,
errorStack: getErrorStack(error)
},
startKey
);
@@ -542,17 +542,19 @@ export default class DocumentsTab extends TabsBase {
startKey
);
},
reason => {
error => {
this.isExecutionError(true);
const message = ErrorParserUtility.parse(reason)[0].message;
window.alert(message);
const errorMessage = getErrorMessage(error);
window.alert(errorMessage);
TelemetryProcessor.traceFailure(
Action.UpdateDocument,
{
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: errorMessage,
errorStack: getErrorStack(error)
},
startKey
);
@@ -643,7 +645,8 @@ export default class DocumentsTab extends TabsBase {
defaultExperience: this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle(),
error: error
error: getErrorMessage(error),
errorStack: getErrorStack(error)
},
this.onLoadStartKey
);
@@ -697,16 +700,18 @@ export default class DocumentsTab extends TabsBase {
startKey
);
},
reason => {
error => {
this.isExecutionError(true);
console.error(reason);
console.error(error);
TelemetryProcessor.traceFailure(
Action.DeleteDocument,
{
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: getErrorMessage(error),
errorStack: getErrorStack(error)
},
startKey
);
@@ -787,7 +792,8 @@ export default class DocumentsTab extends TabsBase {
defaultExperience: this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle(),
error: errorMessage
error: errorMessage,
errorStack: getErrorStack(error)
},
this.onLoadStartKey
);

View File

@@ -4,7 +4,6 @@ import * as ko from "knockout";
import * as ViewModels from "../../Contracts/ViewModels";
import DocumentId from "../Tree/DocumentId";
import DocumentsTab from "./DocumentsTab";
import * as ErrorParserUtility from "../../Common/ErrorParserUtility";
import MongoUtility from "../../Common/MongoUtility";
import ObjectId from "../Tree/ObjectId";
import Q from "q";
@@ -20,6 +19,7 @@ import {
import { extractPartitionKey } from "@azure/cosmos";
import * as Logger from "../../Common/Logger";
import { PartitionKeyDefinition } from "@azure/cosmos";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
export default class MongoDocumentsTab extends DocumentsTab {
public collection: ViewModels.Collection;
@@ -72,7 +72,8 @@ export default class MongoDocumentsTab extends DocumentsTab {
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: message
},
startKey
);
@@ -114,17 +115,19 @@ export default class MongoDocumentsTab extends DocumentsTab {
startKey
);
},
reason => {
error => {
this.isExecutionError(true);
const message = ErrorParserUtility.parse(reason)[0].message;
window.alert(message);
const errorMessage = getErrorMessage(error);
window.alert(errorMessage);
TelemetryProcessor.traceFailure(
Action.CreateDocument,
{
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: errorMessage,
errorStack: getErrorStack(error)
},
startKey
);
@@ -176,17 +179,19 @@ export default class MongoDocumentsTab extends DocumentsTab {
startKey
);
},
reason => {
error => {
this.isExecutionError(true);
const message = ErrorParserUtility.parse(reason)[0].message;
window.alert(message);
const errorMessage = getErrorMessage(error);
window.alert(errorMessage);
TelemetryProcessor.traceFailure(
Action.UpdateDocument,
{
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: errorMessage,
errorStack: getErrorStack(error)
},
startKey
);
@@ -267,7 +272,8 @@ export default class MongoDocumentsTab extends DocumentsTab {
defaultExperience: this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle(),
error: error
error: getErrorMessage(error),
errorStack: getErrorStack(error)
},
this.onLoadStartKey
);

View File

@@ -47,7 +47,7 @@
</script>
<!-- Query Errors Tab - Start-->
<div class="active queryErrorsHeaderContainer" data-bind="visible: errors().length > 0">
<div class="active queryErrorsHeaderContainer" data-bind="visible: !!error()">
<span class="queryErrors" data-toggle="tab" data-bind="attr: { href: '#queryerrors' + tabId }">Errors</span>
</div>
<!-- Query Errors Tab - End -->
@@ -56,16 +56,16 @@
<div class="queryResultErrorContentContainer">
<div
class="queryEditorWatermark"
data-bind="visible: allResultsMetadata().length === 0 && errors().length === 0 && !queryResults() && !isExecuting()"
data-bind="visible: allResultsMetadata().length === 0 && !error() && !queryResults() && !isExecuting()"
>
<p><img src="/RunQuery.png" alt="Execute Query Watermark" /></p>
<p class="queryEditorWatermarkText">Execute a query to see the results</p>
</div>
<div
class="queryResultsErrorsContent"
data-bind="visible: allResultsMetadata().length > 0 || errors().length > 0 || queryResults()"
data-bind="visible: allResultsMetadata().length > 0 || !!error() || queryResults()"
>
<div class="togglesWithMetadata" data-bind="visible: errors().length === 0">
<div class="togglesWithMetadata" data-bind="visible: !error()">
<div
class="toggles"
aria-label="Successful execution"
@@ -103,12 +103,12 @@
</div>
<json-editor
params="{ content: queryResults, isReadOnly: true, ariaLabel: 'Query results' }"
data-bind="visible: queryResults().length > 0 && isResultToggled() && allResultsMetadata().length > 0 && errors().length === 0"
data-bind="visible: queryResults().length > 0 && isResultToggled() && allResultsMetadata().length > 0 && !error()"
>
</json-editor>
<div
class="queryMetricsSummaryContainer"
data-bind="visible: isMetricsToggled() && allResultsMetadata().length > 0 && errors().length === 0"
data-bind="visible: isMetricsToggled() && allResultsMetadata().length > 0 && !error()"
>
<table class="queryMetricsSummary">
<caption>
@@ -308,11 +308,10 @@
id: {
href: 'queryerrors' + tabId
},
visible: errors().length > 0"
visible: !!error()"
>
<!-- ko foreach: errors -->
<div class="errorContent">
<span class="errorMessage" data-bind="text: $data.message"></span>
<span class="errorMessage" data-bind="text: error"></span>
<span class="errorDetailsLink">
<a
data-bind="click: $parent.onErrorDetailsClick, event: { keypress: $parent.onErrorDetailsKeyPress }"
@@ -323,7 +322,6 @@
>
</span>
</div>
<!-- /ko -->
</div>
<!-- Query Errors Content - End-->
</div>

View File

@@ -4,7 +4,6 @@ import * as Constants from "../../Common/Constants";
import * as DataModels from "../../Contracts/DataModels";
import * as ViewModels from "../../Contracts/ViewModels";
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
import * as ErrorParserUtility from "../../Common/ErrorParserUtility";
import TabsBase from "./TabsBase";
import { HashMap } from "../../Common/HashMap";
import * as HeadersUtility from "../../Common/HeadersUtility";
@@ -18,6 +17,7 @@ import SaveQueryIcon from "../../../images/save-cosmos.svg";
import { MinimalQueryIterator } from "../../Common/IteratorUtilities";
import { queryDocuments, queryDocumentsPage } from "../../Common/DocumentClientUtilityBase";
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
enum ToggleState {
Result,
@@ -34,7 +34,7 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem
public selectedContent: ko.Observable<string>;
public sqlStatementToExecute: ko.Observable<string>;
public queryResults: ko.Observable<string>;
public errors: ko.ObservableArray<ViewModels.QueryError>;
public error: ko.Observable<string>;
public statusMessge: ko.Observable<string>;
public statusIcon: ko.Observable<string>;
public allResultsMetadata: ko.ObservableArray<ViewModels.QueryResultsMetadata>;
@@ -82,7 +82,7 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem
this.statusMessge = ko.observable<string>();
this.statusIcon = ko.observable<string>();
this.allResultsMetadata = ko.observableArray<ViewModels.QueryResultsMetadata>([]);
this.errors = ko.observableArray<ViewModels.QueryError>([]);
this.error = ko.observable<string>();
this._partitionKey = options.partitionKey;
this._resourceTokenPartitionKey = options.resourceTokenPartitionKey;
this.splitterId = this.tabId + "_splitter";
@@ -266,7 +266,7 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem
};
private _executeQueryDocumentsPage(firstItemIndex: number): Q.Promise<any> {
this.errors([]);
this.error("");
this.roundTrips(undefined);
if (this._iterator == null) {
const queryIteratorPromise = this._initIterator();
@@ -350,27 +350,19 @@ export default class QueryTab extends TabsBase implements ViewModels.WaitsForTem
startKey
);
},
(reason: any) => {
(error: any) => {
this.isExecutionError(true);
const parsedErrors = ErrorParserUtility.parse(reason);
var errors = parsedErrors.map((error: DataModels.ErrorDataModel) => {
return <ViewModels.QueryError>{
message: error.message,
start: error.location ? error.location.start : undefined,
end: error.location ? error.location.end : undefined,
code: error.code,
severity: error.severity
};
});
this.errors(errors);
const errorMessage = getErrorMessage(error);
this.error(errorMessage);
TelemetryProcessor.traceFailure(
Action.ExecuteQuery,
{
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: errorMessage,
errorStack: getErrorStack(error)
},
startKey
);

View File

@@ -22,7 +22,7 @@ import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandBu
import { userContext } from "../../UserContext";
import { updateOfferThroughputBeyondLimit } from "../../Common/dataAccess/updateOfferThroughputBeyondLimit";
import { configContext, Platform } from "../../ConfigContext";
import { getErrorMessage } from "../../Common/ErrorHandlingUtils";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
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.
@@ -1175,7 +1175,8 @@ export default class SettingsTab extends TabsBase implements ViewModels.WaitsFor
defaultExperience: this.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle(),
error: getErrorMessage(error)
error: getErrorMessage(error),
errorStack: getErrorStack(error)
},
startKey
);

View File

@@ -9,6 +9,7 @@ import ko from "knockout";
import * as Constants from "../../Common/Constants";
import { Action } from "../../Shared/Telemetry/TelemetryConstants";
import { logConsoleError } from "../../Utils/NotificationConsoleUtils";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
export default class SettingsTabV2 extends TabsBase {
public settingsComponentAdapter: SettingsComponentAdapter;
@@ -55,6 +56,7 @@ export default class SettingsTabV2 extends TabsBase {
this.isExecuting(false);
},
error => {
const errorMessage = getErrorMessage(error);
this.notification = undefined;
this.notificationRead(true);
this.isExecuting(false);
@@ -67,14 +69,13 @@ export default class SettingsTabV2 extends TabsBase {
defaultExperience: this.options.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle,
error: error
error: errorMessage,
errorStack: getErrorStack(error)
},
this.options.onLoadStartKey
);
logConsoleError(
`Error while fetching container settings for container ${this.options.collection.id()}: ${JSON.stringify(
error
)}`
`Error while fetching container settings for container ${this.options.collection.id()}: ${errorMessage}`
);
throw error;
}

View File

@@ -13,6 +13,7 @@ import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import { CommandButtonComponentProps } from "../Controls/CommandButton/CommandButtonComponent";
import StoredProcedure from "../Tree/StoredProcedure";
import ScriptTabBase from "./ScriptTabBase";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
enum ToggleState {
Result = "result",
@@ -104,7 +105,7 @@ export default class StoredProcedureTab extends ScriptTabBase {
startKey
);
},
(updateError: any) => {
(error: any) => {
this.isExecutionError(true);
TelemetryProcessor.traceFailure(
Action.UpdateStoredProcedure,
@@ -112,7 +113,9 @@ export default class StoredProcedureTab extends ScriptTabBase {
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: getErrorMessage(error),
errorStack: getErrorStack(error)
},
startKey
);
@@ -274,7 +277,9 @@ export default class StoredProcedureTab extends ScriptTabBase {
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: getErrorMessage(createError),
errorStack: getErrorStack(createError)
},
startKey
);

View File

@@ -8,6 +8,7 @@ import { Action } from "../../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import Trigger from "../Tree/Trigger";
import ScriptTabBase from "./ScriptTabBase";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
export default class TriggerTab extends ScriptTabBase {
public collection: ViewModels.Collection;
@@ -86,7 +87,9 @@ export default class TriggerTab extends ScriptTabBase {
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: getErrorMessage(createError),
errorStack: getErrorStack(createError)
},
startKey
);
@@ -168,7 +171,9 @@ export default class TriggerTab extends ScriptTabBase {
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: getErrorMessage(createError),
errorStack: getErrorStack(createError)
},
startKey
);

View File

@@ -7,6 +7,7 @@ import { Action } from "../../Shared/Telemetry/TelemetryConstants";
import * as TelemetryProcessor from "../../Shared/Telemetry/TelemetryProcessor";
import UserDefinedFunction from "../Tree/UserDefinedFunction";
import ScriptTabBase from "./ScriptTabBase";
import { getErrorMessage, getErrorStack } from "../../Common/ErrorHandlingUtils";
export default class UserDefinedFunctionTab extends ScriptTabBase {
public collection: ViewModels.Collection;
@@ -68,7 +69,9 @@ export default class UserDefinedFunctionTab extends ScriptTabBase {
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: getErrorMessage(createError),
errorStack: getErrorStack(createError)
},
startKey
);
@@ -143,7 +146,9 @@ export default class UserDefinedFunctionTab extends ScriptTabBase {
databaseAccountName: this.collection && this.collection.container.databaseAccount().name,
defaultExperience: this.collection && this.collection.container.defaultExperience(),
dataExplorerArea: Constants.Areas.Tab,
tabTitle: this.tabTitle()
tabTitle: this.tabTitle(),
error: getErrorMessage(createError),
errorStack: getErrorStack(createError)
},
startKey
);