diff --git a/packages/grpc-js-xds/src/resolver-xds.ts b/packages/grpc-js-xds/src/resolver-xds.ts index 80c38518..0c1d9628 100644 --- a/packages/grpc-js-xds/src/resolver-xds.ts +++ b/packages/grpc-js-xds/src/resolver-xds.ts @@ -135,18 +135,12 @@ class XdsResolver implements Resolver { this.xdsClient = getSingletonXdsClient(); } this.xdsConfigWatcher = { - onUpdate: xdsConfig => { - this.handleXdsConfig(xdsConfig); - }, - onError: (context, status) => { - trace('Resolution error for target ' + uriToString(this.target) + ' due to xDS client transient error retrieving ' + context + ': ' + status.details); - this.reportResolutionError(`Error retrieving resource ${context}: ${status.details}`); - }, - onResourceDoesNotExist: context => { - trace('Resolution error for target ' + uriToString(this.target) + ': ' + context + ' does not exist'); - /* Return an empty endpoint list and service config, to explicitly - * invalidate any previously returned service config */ - this.listener(statusOrFromValue([]), {}, null, ''); + onUpdate: maybeXdsConfig => { + if (maybeXdsConfig.ok) { + this.handleXdsConfig(maybeXdsConfig.value); + } else { + this.listener(statusOrFromValue([]), {}, null, `Resolution error for target ${uriToString(this.target)}: ${maybeXdsConfig.error.details}`); + } } } } diff --git a/packages/grpc-js-xds/src/xds-dependency-manager.ts b/packages/grpc-js-xds/src/xds-dependency-manager.ts index 1263d18a..c16f9748 100644 --- a/packages/grpc-js-xds/src/xds-dependency-manager.ts +++ b/packages/grpc-js-xds/src/xds-dependency-manager.ts @@ -89,9 +89,7 @@ export interface XdsConfig { } export interface XdsConfigWatcher { - onUpdate(xdsConfig: XdsConfig): void; - onError(context: string, status: StatusObject): void; - onResourceDoesNotExist(context: string): void; + onUpdate(xdsConfig: StatusOr): void; } interface AggregateClusterInfo { @@ -394,7 +392,13 @@ export class XdsDependencyManager { * not already provided a ServiceConfig for the upper layer to use */ if (!this.latestListener) { this.trace('Resolution error due to xDS client transient error ' + error.details); - this.watcher.onError(`Listener ${listenerResourceName}`, error); + this.watcher.onUpdate({ + ok: false, + error: { + ...error, + details: `Listener ${listenerResourceName}: ${error.details}` + } + }); } }, onResourceDoesNotExist: () => { @@ -408,11 +412,24 @@ export class XdsDependencyManager { }, onError: (error: StatusObject) => { if (!this.latestRouteConfiguration) { - this.watcher.onError(`RouteConfiguration ${this.latestRouteConfigName}`, error); + this.watcher.onUpdate({ + ok: false, + error: { + ...error, + details: `RouteConfiguration ${this.latestRouteConfigName}: ${error.details}` + } + }); } }, onResourceDoesNotExist: () => { - this.watcher.onResourceDoesNotExist(`RouteConfiguration ${this.latestRouteConfigName}`); + this.watcher.onUpdate({ + ok: false, + error: { + code: status.UNAVAILABLE, + details: `RouteConfiguration ${this.latestRouteConfigName} does not exist`, + metadata: new Metadata() + } + }); this.clusterRoots = []; this.pruneOrphanClusters(); } @@ -434,8 +451,14 @@ export class XdsDependencyManager { this.clusterRoots = []; this.pruneOrphanClusters(); } - this.watcher.onResourceDoesNotExist(`Listener ${this.listenerResourceName}`); - + this.watcher.onUpdate({ + ok: false, + error: { + code: status.UNAVAILABLE, + details: `Listener ${this.listenerResourceName} does not exist`, + metadata: new Metadata() + } + }); } private maybeSendUpdate() { @@ -491,7 +514,7 @@ export class XdsDependencyManager { }); } } - this.watcher.onUpdate(update); + this.watcher.onUpdate({ok: true, value: update}); } private addCluster(clusterName: string) { @@ -763,10 +786,13 @@ export class XdsDependencyManager { if (!virtualHost) { this.clusterRoots = []; this.pruneOrphanClusters(); - this.watcher.onError(`RouteConfiguration ${routeConfig.name}`, { - code: status.UNAVAILABLE, - details: `No matching route found for ${this.dataPlaneAuthority}`, - metadata: new Metadata() + this.watcher.onUpdate({ + ok: false, + error: { + code: status.UNAVAILABLE, + details: `RouteConfiguration ${routeConfig.name}: No matching route found for ${this.dataPlaneAuthority}`, + metadata: new Metadata() + } }); // Report error return;