Skip to content
This repository has been archived by the owner on Aug 15, 2019. It is now read-only.

catch all unhandled promise rejection for http browser io handler #1455

Merged
merged 23 commits into from Jan 24, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ac52e66
add try catch to all await call
pyu10055 Dec 13, 2018
32a771e
added accept header for request and response header check
pyu10055 Dec 20, 2018
8a41afb
Merge branch 'master' into catch_promise_error
pyu10055 Dec 20, 2018
8b4b92a
fix error message
pyu10055 Dec 20, 2018
9c3a195
Merge branch 'catch_promise_error' of github.com:tensorflow/tfjs-core…
pyu10055 Dec 20, 2018
a094811
WIP wrap the fetch func with global catch
pyu10055 Dec 21, 2018
9422c57
fixed header being shared between requests
pyu10055 Dec 21, 2018
371981c
fix node.js missing Header class error
pyu10055 Dec 21, 2018
9b5339d
fix node.js error
pyu10055 Dec 21, 2018
7847656
remove use of Response
pyu10055 Dec 21, 2018
9f6ff2c
fixed weight load test failure
pyu10055 Dec 21, 2018
dbe8da2
Merge branch 'master' into catch_promise_error
pyu10055 Dec 26, 2018
ff05b09
Merge branch 'master' into catch_promise_error
pyu10055 Jan 4, 2019
96c063d
addressed comments
pyu10055 Jan 10, 2019
7a55301
Merge branches 'catch_promise_error' and 'catch_promise_error' of git…
pyu10055 Jan 10, 2019
e8e701f
more changes for comments
pyu10055 Jan 10, 2019
7ef2ede
add the any type back
pyu10055 Jan 10, 2019
e650dde
Merge branch 'master' into catch_promise_error
pyu10055 Jan 10, 2019
8c1458c
Merge branch 'master' into catch_promise_error
pyu10055 Jan 15, 2019
16de246
Merge branch 'master' into catch_promise_error
pyu10055 Jan 24, 2019
3e072f7
address comments
pyu10055 Jan 24, 2019
35258df
remove lint line
pyu10055 Jan 24, 2019
b5f8e7a
Merge branch 'master' into catch_promise_error
pyu10055 Jan 24, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
139 changes: 85 additions & 54 deletions src/io/browser_http.ts
Expand Up @@ -145,72 +145,100 @@ export class BrowserHTTPRequest implements IOHandler {
*/
private async loadBinaryTopology(): Promise<ArrayBuffer> {
try {
const response =
await this.getFetchFunc()(this.path[0], this.requestInit);
const response = await this.getFetchFunc()(
this.path[0], this.addAcceptHeader('application/octet-stream'));
this.verifyContentType(response, 'application/octet-stream');

if (!response.ok) {
throw new Error(
`BrowserHTTPRequest.load() failed due to HTTP response: ${
response.statusText}`);
throw new Error(`Request to ${this.path[0]} failed with error: ${
response.statusText}`);
}
return await response.arrayBuffer();
} catch (error) {
throw new Error(`${this.path[0]} not found. ${error}`);
throw new Error(`Failed to load ${this.path[0]}. ${error}`);
}
}

protected async loadBinaryModel(): Promise<ModelArtifacts> {
const graphPromise = this.loadBinaryTopology();
const manifestPromise =
await this.getFetchFunc()(this.path[1], this.requestInit);
if (!manifestPromise.ok) {
throw new Error(`BrowserHTTPRequest.load() failed due to HTTP response: ${
manifestPromise.statusText}`);
private addAcceptHeader(mimeType: string): RequestInit {
const requestOptions = Object.assign({}, this.requestInit || {});
const headers = new Headers(requestOptions.headers);
headers.append('Accept', mimeType);
requestOptions.headers = headers;
return requestOptions;
}

private verifyContentType(response: Response, target: string) {
const contentType = response.headers.get('content-type');
if (!contentType || contentType.indexOf(target) === -1) {
throw new Error(`Wrong content type (${contentType}) for ${
response.url}, should be (${target}).`);
}
}

protected async loadBinaryModel(): Promise<ModelArtifacts> {
try {
const graphPromise = this.loadBinaryTopology();
const manifestPromise = await this.getFetchFunc()(
this.path[1], this.addAcceptHeader('application/json'));
this.verifyContentType(manifestPromise, 'application/json');
if (!manifestPromise.ok) {
throw new Error(`Request to ${this.path[1]} failed with error: ${
manifestPromise.statusText}`);
}

const results = await Promise.all([graphPromise, manifestPromise]);
const [modelTopology, weightsManifestResponse] = results;
const results = await Promise.all([graphPromise, manifestPromise]);
const [modelTopology, weightsManifestResponse] = results;

const weightsManifest =
await weightsManifestResponse.json() as WeightsManifestConfig;
const weightsManifest =
await weightsManifestResponse.json() as WeightsManifestConfig;

let weightSpecs: WeightsManifestEntry[];
let weightData: ArrayBuffer;
if (weightsManifest != null) {
const results = await this.loadWeights(weightsManifest);
[weightSpecs, weightData] = results;
}
let weightSpecs: WeightsManifestEntry[];
let weightData: ArrayBuffer;
if (weightsManifest != null) {
const results = await this.loadWeights(weightsManifest);
[weightSpecs, weightData] = results;
}

return {modelTopology, weightSpecs, weightData};
return {modelTopology, weightSpecs, weightData};
} catch (error) {
throw new Error(`Request to ${this.path[1]} failed with error: ${error}`);
}
}

protected async loadJSONModel(): Promise<ModelArtifacts> {
const modelConfigRequest =
await this.getFetchFunc()(this.path as string, this.requestInit);
if (!modelConfigRequest.ok) {
throw new Error(`BrowserHTTPRequest.load() failed due to HTTP response: ${
modelConfigRequest.statusText}`);
}
const modelConfig = await modelConfigRequest.json();
const modelTopology = modelConfig['modelTopology'];
const weightsManifest = modelConfig['weightsManifest'];
try {
const modelConfigRequest = await this.getFetchFunc()(
this.path as string, this.addAcceptHeader('application/json'));
this.verifyContentType(modelConfigRequest, 'application/json');

// We do not allow both modelTopology and weightsManifest to be missing.
if (modelTopology == null && weightsManifest == null) {
throw new Error(
`The JSON from HTTP path ${this.path} contains neither model ` +
`topology or manifest for weights.`);
}
if (!modelConfigRequest.ok) {
throw new Error(`Request to ${this.path} failed with error: ${
modelConfigRequest.statusText}`);
}
const modelConfig = await modelConfigRequest.json();
const modelTopology = modelConfig['modelTopology'];
const weightsManifest = modelConfig['weightsManifest'];

let weightSpecs: WeightsManifestEntry[];
let weightData: ArrayBuffer;
if (weightsManifest != null) {
const weightsManifest =
modelConfig['weightsManifest'] as WeightsManifestConfig;
const results = await this.loadWeights(weightsManifest);
[weightSpecs, weightData] = results;
}
// We do not allow both modelTopology and weightsManifest to be missing.
if (modelTopology == null && weightsManifest == null) {
throw new Error(
`The JSON from HTTP path ${this.path} contains neither model ` +
`topology or manifest for weights.`);
}

return {modelTopology, weightSpecs, weightData};
let weightSpecs: WeightsManifestEntry[];
let weightData: ArrayBuffer;
if (weightsManifest != null) {
const weightsManifest =
modelConfig['weightsManifest'] as WeightsManifestConfig;
const results = await this.loadWeights(weightsManifest);
[weightSpecs, weightData] = results;
}

return {modelTopology, weightSpecs, weightData};
} catch (error) {
throw new Error(`Request to ${this.path} failed with error: ${error}`);
}
}

private async loadWeights(weightsManifest: WeightsManifestConfig):
Expand All @@ -230,12 +258,15 @@ export class BrowserHTTPRequest implements IOHandler {
fetchURLs.push(pathPrefix + path + suffix);
});
});

return [
weightSpecs,
concatenateArrayBuffers(await loadWeightsAsArrayBuffer(
fetchURLs, this.requestInit, this.getFetchFunc()))
];
try {
return [
weightSpecs,
concatenateArrayBuffers(await loadWeightsAsArrayBuffer(
fetchURLs, this.requestInit, this.getFetchFunc()))
];
} catch (error) {
throw new Error(`Failed to load weights: ${error}`);
}
}

/**
Expand Down