Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: improve error handling #61

Merged
merged 1 commit into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,36 @@ export class IotAssetDetails {

componentWillLoad() {
this.assetSession = getSiteWiseAssetModule().startSession();
this.assetSession.requestAssetSummary(this.query, (summary: AssetSummary) => {
this.assetSummary = summary;
const assetId = this.assetSummary?.id as string;
const modelQuery: AssetModelQuery = { assetModelId: this.assetSummary.assetModelId as string };
this.assetSession.requestAssetModel(modelQuery, (assetModel: DescribeAssetModelResponse) => {
this.assetModel = assetModel;
assetModel.assetModelProperties?.forEach((prop) => {
let propQuery: AssetPropertyValueQuery = { assetId: assetId, propertyId: prop.id as string };
this.assetSession.requestAssetPropertyValue(propQuery, (propValue: AssetPropertyValue) => {
const copy = new Map(this.assetPropertyValues);
copy.set(prop.id as string, this.convertToString(propValue));
this.assetPropertyValues = copy;
});
this.assetSession.requestAssetSummary(this.query, {
next: (summary: AssetSummary) => {
this.assetSummary = summary;
const assetId = this.assetSummary?.id as string;
const modelQuery: AssetModelQuery = { assetModelId: this.assetSummary.assetModelId as string };
this.assetSession.requestAssetModel(modelQuery, {
next: (assetModel: DescribeAssetModelResponse) => {
this.assetModel = assetModel;
assetModel.assetModelProperties?.forEach((prop) => {
let propQuery: AssetPropertyValueQuery = { assetId: assetId, propertyId: prop.id as string };
this.assetSession.requestAssetPropertyValue(propQuery, {
next: (propValue: AssetPropertyValue) => {
const copy = new Map(this.assetPropertyValues);
copy.set(prop.id as string, this.convertToString(propValue));
this.assetPropertyValues = copy;
},
error: (err) => {
// noop
},
});
});
},
error: (err) => {
// noop
},
});
});
},
error: (err) => {
// noop
},
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ export class IotAssetTreeDemo {
let session: SiteWiseAssetTreeSession = new SiteWiseAssetTreeModule(getSiteWiseAssetModule()).startSession(
this.query
);
this.subscription = session.subscribe((newTree) => {
this.roots = newTree;
// check the tree for any new unexpanded nodes and expand them:
this.expandNodes(newTree);
this.subscription = session.subscribe({
next: (newTree) => {
this.roots = newTree;
// check the tree for any new unexpanded nodes and expand them:
this.expandNodes(newTree);
},
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import {
IoTAppKit,
SiteWiseAssetTreeNode,
SiteWiseAssetTreeQuery,
ErrorDetails,
} from '@iot-app-kit/core';
import { SitewiseAssetResource } from './types';
import { SitewiseAssetResource, FilterTexts, ColumnDefinition } from './types';
import { EmptyStateProps, ITreeNode, UseTreeCollection } from '@iot-app-kit/related-table';
import { parseSitewiseAssetTree } from './utils';
import { TableProps } from '@awsui/components-react/table';
import { FilterTexts, ColumnDefinition } from './types';
import { NonCancelableCustomEvent } from '@awsui/components-react';

@Component({
Expand All @@ -33,6 +33,8 @@ export class SitewiseResourceExplorer {

@State() items: SitewiseAssetResource[] = [];

@State() errors: ErrorDetails[] = [];

defaults = {
selectionType: 'single' as TableProps.SelectionType,
loadingText: 'loading...',
Expand All @@ -50,9 +52,14 @@ export class SitewiseResourceExplorer {
subscription: AssetTreeSubscription;

componentWillLoad() {
this.subscription = this.appKit.subscribeToAssetTree(this.query, (newTree: SiteWiseAssetTreeNode[]) => {
this.items = parseSitewiseAssetTree(newTree);
});
this.subscription = this.appKit.subscribeToAssetTree(this.query, {
next: (newTree: SiteWiseAssetTreeNode[]) => {
this.items = parseSitewiseAssetTree(newTree);
},
error: (err: ErrorDetails[]) => {
this.errors = err;
},
}) as AssetTreeSubscription;
}

componentWillUnmount() {
Expand Down Expand Up @@ -87,6 +94,18 @@ export class SitewiseResourceExplorer {
if (this.paginationEnabled) {
collectionOptions.pagination = { pageSize: 20 };
}

let empty: EmptyStateProps = this.defaults.empty;

if (this.empty) {
empty = this.empty;
}

if (this.errors.length > 0) {
// TODO: Make use of all the errors
empty = { header: 'Error', description: this.errors[this.errors.length - 1]?.msg };
}

return (
<iot-tree-table
items={this.items}
Expand All @@ -97,7 +116,7 @@ export class SitewiseResourceExplorer {
filterPlaceholder={filtering?.placeholder}
onExpandChildren={this.expandNode}
onSelectionChange={this.onSelectionChange}
empty={this.empty || this.defaults.empty}
empty={empty}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was not able to test this with @stencil/core/testing, I want to backfill on these tests with cypress component testing as part of the next task of backfilling integration tests for components.

sortingDisabled={!this.sortingEnabled}
wrapLines={this.wrapLines}
></iot-tree-table>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
const STRING_ASSET_ID = 'f2f74fa8-625a-435f-b89c-d27b2d84f45b';
const STRING_PROPERTY_ID = '797482e4-692f-45a2-b3db-17979481e9c3';

export const DEMO_TURBINE_ASSET_1 = 'f2f74fa8-625a-435f-b89c-d27b2d84f45b';
export const DEMO_TURBINE_ASSET_1 = '00eeb4b1-5017-48d4-9f39-1066f080a822';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nooo, my poor assets IDs :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha, yeah we probably want to clean this up before we go public.


export const DEMO_TURBINE_ASSET_1_PROPERTY_1 = 'd0dc79be-0dc2-418c-ac23-26f33cdb4b8b';
export const DEMO_TURBINE_ASSET_1_PROPERTY_2 = '69607dc2-5fbe-416d-aac2-0382018626e4';
export const DEMO_TURBINE_ASSET_1_PROPERTY_3 = '26072fa0-e36e-489d-90b4-1774e7d12ac9';
export const DEMO_TURBINE_ASSET_1_PROPERTY_4 = '5c2b7401-57e0-4205-97f2-c4348f12da9a';
export const DEMO_TURBINE_ASSET_1_PROPERTY_1 = '8739b557-3e77-4df9-9862-130b29dee2b1';
export const DEMO_TURBINE_ASSET_1_PROPERTY_2 = '9701d7ad-c22e-43fd-b040-68bad00317e3';
export const DEMO_TURBINE_ASSET_1_PROPERTY_3 = 'bded202a-a436-46b8-85c1-21bb5b945f86';
export const DEMO_TURBINE_ASSET_1_PROPERTY_4 = 'd8937b65-5f03-4e40-93ac-c5513420ade7';

export const STRING_QUERY = {
source: 'site-wise',
Expand All @@ -27,9 +27,9 @@ export const NUMBER_QUERY = {
],
};

const AGGREGATED_DATA_ASSET = 'f2f74fa8-625a-435f-b89c-d27b2d84f45b';
const AGGREGATED_DATA_PROPERTY = 'd0dc79be-0dc2-418c-ac23-26f33cdb4b8b';
const AGGREGATED_DATA_PROPERTY_2 = '69607dc2-5fbe-416d-aac2-0382018626e4';
const AGGREGATED_DATA_ASSET = '099b1330-83ff-4fec-b165-c7186ec8eb23';
const AGGREGATED_DATA_PROPERTY = '05c5c47f-fd92-4823-828e-09ce63b90569';
const AGGREGATED_DATA_PROPERTY_2 = '11d2599a-2547-451d-ab79-a47f878dbbe3';

export const AGGREGATED_DATA_QUERY = {
assets: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export class TestingGround {
<iot-line-chart
appKit={this.appKit}
viewport={this.viewport}
settings={{ resolution: this.resolution, requestBuffer: 1 }}
queries={[query.iotsitewise.timeSeriesData(AGGREGATED_DATA_QUERY)]}
/>
</div>
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/asset-modules/coordinator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SiteWiseAssetSession } from './sitewise/session';
import { SiteWiseAssetTreeCallback, SiteWiseAssetTreeQuery } from './sitewise-asset-tree/types';
import { SiteWiseAssetTreeObserver, SiteWiseAssetTreeQuery } from './sitewise-asset-tree/types';
import { SiteWiseAssetTreeSession } from './sitewise-asset-tree/assetTreeSession';

export const subscribeToAssetTree =
(assetModuleSession: SiteWiseAssetSession) => (query: SiteWiseAssetTreeQuery, callback: SiteWiseAssetTreeCallback) =>
new SiteWiseAssetTreeSession(assetModuleSession, query).subscribe(callback);
(assetModuleSession: SiteWiseAssetSession) => (query: SiteWiseAssetTreeQuery, observer: SiteWiseAssetTreeObserver) =>
new SiteWiseAssetTreeSession(assetModuleSession, query).subscribe(observer);
52 changes: 44 additions & 8 deletions packages/core/src/asset-modules/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import {
} from './sitewise/types';
import { AssetPropertyValue, AssetSummary, DescribeAssetModelResponse } from '@aws-sdk/client-iotsitewise';
import { lastValueFrom, Observable, Subscription } from 'rxjs';
import { ErrorDetails } from '../common/types';

export class MockSiteWiseAssetsReplayData {
public models: Map<string, DescribeAssetModelResponse> = new Map<string, DescribeAssetModelResponse>();
public hierarchies: Map<string, HierarchyAssetSummaryList> = new Map<string, HierarchyAssetSummaryList>();
public properties: Map<string, AssetPropertyValue> = new Map<string, AssetPropertyValue>();
public assets: Map<string, AssetSummary> = new Map<string, AssetSummary>();
public errors: ErrorDetails[] = [];

public addAssetModels(newModels: DescribeAssetModelResponse[]) {
newModels.forEach((model) => this.models.set(model.assetModelId as string, model));
Expand All @@ -33,6 +35,10 @@ export class MockSiteWiseAssetsReplayData {
) {
this.hierarchies.set(assetHierarchyQueryKey(query), newHierarchyAssetSummaryList);
}

public addErrors(errors: ErrorDetails[]) {
this.errors = [...this.errors, ...errors];
}
}

export class MockSiteWiseAssetSession implements SiteWiseAssetSessionInterface {
Expand All @@ -44,10 +50,20 @@ export class MockSiteWiseAssetSession implements SiteWiseAssetSessionInterface {

private _requestAssetSummary(query: { assetId: string }): Observable<AssetSummary> {
return new Observable<AssetSummary>((observer) => {
observer.next(this.replayData.assets.get(query.assetId));
if (this.replayData.errors.length > 0) {
observer.error(this.replayData.errors);
} else {
observer.next(this.replayData.assets.get(query.assetId));
}
});
}
requestAssetSummary(query: { assetId: string }, observer: (assetSummary: AssetSummary) => void): Subscription {
requestAssetSummary(
query: { assetId: string },
observer: {
next: (assetSummary: AssetSummary) => void;
error?: (err: ErrorDetails[]) => void;
}
): Subscription {
return this._requestAssetSummary(query).subscribe(observer);
}
fetchAssetSummary(query: { assetId: string }): Promise<AssetSummary> {
Expand All @@ -61,7 +77,10 @@ export class MockSiteWiseAssetSession implements SiteWiseAssetSessionInterface {
}
requestAssetModel(
query: { assetModelId: string },
observer: (assetSummary: DescribeAssetModelResponse) => void
observer: {
next: (assetSummary: DescribeAssetModelResponse) => void;
error?: (err: ErrorDetails[]) => void;
}
): Subscription {
return this._requestAssetModel(query).subscribe(observer);
}
Expand All @@ -76,7 +95,10 @@ export class MockSiteWiseAssetSession implements SiteWiseAssetSessionInterface {
}
requestAssetPropertyValue(
query: { assetId: string; propertyId: string },
observer: (assetSummary: AssetPropertyValue) => void
observer: {
next: (assetSummary: AssetPropertyValue) => void;
error?: (err: ErrorDetails[]) => void;
}
): Subscription {
return this._requestAssetPropertyValue(query).subscribe(observer);
}
Expand All @@ -89,12 +111,19 @@ export class MockSiteWiseAssetSession implements SiteWiseAssetSessionInterface {
assetHierarchyId: string;
}): Observable<HierarchyAssetSummaryList> {
return new Observable<HierarchyAssetSummaryList>((observer) => {
observer.next(this.replayData.hierarchies.get(assetHierarchyQueryKey(query)));
if (this.replayData.errors.length > 0) {
observer.error(this.replayData.errors);
} else {
observer.next(this.replayData.hierarchies.get(assetHierarchyQueryKey(query)));
}
});
}
requestAssetHierarchy(
query: { assetId?: string | undefined; assetHierarchyId: string },
observer: (assetSummary: HierarchyAssetSummaryList) => void
observer: {
next: (assetSummary: HierarchyAssetSummaryList) => void;
error?: (err: ErrorDetails[]) => void;
}
): Subscription {
return this._requestAssetHierarchy(query).subscribe(observer);
}
Expand All @@ -107,10 +136,17 @@ export class MockSiteWiseAssetSession implements SiteWiseAssetSessionInterface {

_requestRootAssets(): Observable<HierarchyAssetSummaryList> {
return new Observable<HierarchyAssetSummaryList>((observer) => {
observer.next(this.replayData.hierarchies.get(assetHierarchyQueryKey({ assetHierarchyId: HIERARCHY_ROOT_ID })));
if (this.replayData.errors.length > 0) {
observer.error(this.replayData.errors);
} else {
observer.next(this.replayData.hierarchies.get(assetHierarchyQueryKey({ assetHierarchyId: HIERARCHY_ROOT_ID })));
}
});
}
requestRootAssets(observer: (assetSummary: HierarchyAssetSummaryList) => void): Subscription {
requestRootAssets(observer: {
next: (assetSummary: HierarchyAssetSummaryList) => void;
error?: (err: ErrorDetails[]) => void;
}): Subscription {
return this._requestRootAssets().subscribe(observer);
}
fetchRootAssets(): Promise<HierarchyAssetSummaryList> {
Expand Down
Loading