Commit 3485fa9e authored by hirono's avatar hirono Committed by Commit bot

Files.app: Add error fields to MetadataItem.

Previously if MetadataProvider fails to fetch metaata, there is no way to check
if the entry does not have a property or it fails to obtain the metadata.

The CL adds error fields to MetadataItem, which are cached with corresponding
property.

BUG=410766
TEST=FileManagerJsTest.MetadataCacheItem

Review URL: https://codereview.chromium.org/977873002

Cr-Commit-Position: refs/heads/master@{#319043}
parent d8262e98
...@@ -25,6 +25,7 @@ MetadataCacheItem.prototype.createRequests = function(names) { ...@@ -25,6 +25,7 @@ MetadataCacheItem.prototype.createRequests = function(names) {
var loadRequested = []; var loadRequested = [];
for (var i = 0; i < names.length; i++) { for (var i = 0; i < names.length; i++) {
var name = names[i]; var name = names[i];
assert(!/Error$/.test(name));
// Check if the property needs to be updated. // Check if the property needs to be updated.
if (this.properties_[name] && if (this.properties_[name] &&
this.properties_[name].state !== this.properties_[name].state !==
...@@ -44,6 +45,7 @@ MetadataCacheItem.prototype.createRequests = function(names) { ...@@ -44,6 +45,7 @@ MetadataCacheItem.prototype.createRequests = function(names) {
MetadataCacheItem.prototype.startRequests = function(requestId, names) { MetadataCacheItem.prototype.startRequests = function(requestId, names) {
for (var i = 0; i < names.length; i++) { for (var i = 0; i < names.length; i++) {
var name = names[i]; var name = names[i];
assert(!/Error$/.test(name));
if (!this.properties_[name]) if (!this.properties_[name])
this.properties_[name] = new MetadataCacheItemProperty(); this.properties_[name] = new MetadataCacheItemProperty();
this.properties_[name].requestId = requestId; this.properties_[name].requestId = requestId;
...@@ -61,6 +63,12 @@ MetadataCacheItem.prototype.storeProperties = function(requestId, typedObject) { ...@@ -61,6 +63,12 @@ MetadataCacheItem.prototype.storeProperties = function(requestId, typedObject) {
var changed = false; var changed = false;
var object = /** @type {!Object} */(typedObject); var object = /** @type {!Object} */(typedObject);
for (var name in object) { for (var name in object) {
if (/.Error$/.test(name) && object[name])
object[name.substr(0, name.length - 5)] = undefined;
}
for (var name in object) {
if (/.Error$/.test(name))
continue;
if (!this.properties_[name]) if (!this.properties_[name])
this.properties_[name] = new MetadataCacheItemProperty(); this.properties_[name] = new MetadataCacheItemProperty();
if (requestId < this.properties_[name].requestId || if (requestId < this.properties_[name].requestId ||
...@@ -71,6 +79,7 @@ MetadataCacheItem.prototype.storeProperties = function(requestId, typedObject) { ...@@ -71,6 +79,7 @@ MetadataCacheItem.prototype.storeProperties = function(requestId, typedObject) {
changed = true; changed = true;
this.properties_[name].requestId = requestId; this.properties_[name].requestId = requestId;
this.properties_[name].value = object[name]; this.properties_[name].value = object[name];
this.properties_[name].error = object[name + 'Error'];
this.properties_[name].state = MetadataCacheItemPropertyState.FULFILLED; this.properties_[name].state = MetadataCacheItemPropertyState.FULFILLED;
} }
return changed; return changed;
...@@ -100,8 +109,11 @@ MetadataCacheItem.prototype.get = function(names) { ...@@ -100,8 +109,11 @@ MetadataCacheItem.prototype.get = function(names) {
var result = /** @type {!Object} */(new MetadataItem()); var result = /** @type {!Object} */(new MetadataItem());
for (var i = 0; i < names.length; i++) { for (var i = 0; i < names.length; i++) {
var name = names[i]; var name = names[i];
if (this.properties_[name]) assert(!/Error$/.test(name));
if (this.properties_[name]) {
result[name] = this.properties_[name].value; result[name] = this.properties_[name].value;
result[name + 'Error'] = this.properties_[name].error;
}
} }
return /** @type {!MetadataItem} */(result); return /** @type {!MetadataItem} */(result);
}; };
...@@ -116,6 +128,7 @@ MetadataCacheItem.prototype.clone = function() { ...@@ -116,6 +128,7 @@ MetadataCacheItem.prototype.clone = function() {
var property = this.properties_[name]; var property = this.properties_[name];
clonedItem.properties_[name] = new MetadataCacheItemProperty(); clonedItem.properties_[name] = new MetadataCacheItemProperty();
clonedItem.properties_[name].value = property.value; clonedItem.properties_[name].value = property.value;
clonedItem.properties_[name].error = property.error;
clonedItem.properties_[name].requestId = property.requestId; clonedItem.properties_[name].requestId = property.requestId;
clonedItem.properties_[name].state = property.state; clonedItem.properties_[name].state = property.state;
} }
...@@ -159,6 +172,11 @@ function MetadataCacheItemProperty() { ...@@ -159,6 +172,11 @@ function MetadataCacheItemProperty() {
*/ */
this.value = null; this.value = null;
/**
* @public {Error}
*/
this.error = null;
/** /**
* Last request ID. * Last request ID.
* @public {number} * @public {number}
......
...@@ -81,10 +81,27 @@ function testMetadataCacheItemHasFreshCache() { ...@@ -81,10 +81,27 @@ function testMetadataCacheItemHasFreshCache() {
assertTrue(item.hasFreshCache(['propertyA'])); assertTrue(item.hasFreshCache(['propertyA']));
} }
function testMetadataCacheShouldNotUpdateBeforeInvalidation() { function testMetadataCacheItemShouldNotUpdateBeforeInvalidation() {
var item = new MetadataCacheItem(); var item = new MetadataCacheItem();
item.startRequests(1, item.createRequests(['property'])); item.startRequests(1, item.createRequests(['property']));
item.storeProperties(1, {property: 'value1'}); item.storeProperties(1, {property: 'value1'});
item.storeProperties(2, {property: 'value2'}); item.storeProperties(2, {property: 'value2'});
assertEquals('value1', item.get(['property']).property); assertEquals('value1', item.get(['property']).property);
} }
function testMetadataCacheItemError() {
var item = new MetadataCacheItem();
item.startRequests(1, item.createRequests(['property']));
item.storeProperties(
1, {property: 'value1', propertyError: new Error('Error')});
assertEquals(undefined, item.get(['property']).property);
assertEquals('Error', item.get(['property']).propertyError.message);
}
function testMetadataCacheItemErrorShouldNotFetchedDirectly() {
var item = new MetadataCacheItem();
item.startRequests(1, item.createRequests(['property']));
item.storeProperties(
1, {property: 'value1', propertyError: new Error('Error')});
assertThrows(function() { item.get(['propertyError']); });
}
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
var ImageTransformation; var ImageTransformation;
/** /**
* Each property of MetadataItem has error property also.
* @constructor * @constructor
* @struct * @struct
*/ */
...@@ -22,123 +23,233 @@ function MetadataItem() { ...@@ -22,123 +23,233 @@ function MetadataItem() {
*/ */
this.size; this.size;
/**
* @public {Error|undefined}
*/
this.sizeError;
/** /**
* @public {!Date|undefined} * @public {!Date|undefined}
*/ */
this.modificationTime; this.modificationTime;
/**
* @public {Error|undefined}
*/
this.modificationTimeError;
/** /**
* Thumbnail URL obtained from external provider. * Thumbnail URL obtained from external provider.
* @public {string|undefined} * @public {string|undefined}
*/ */
this.thumbnailUrl; this.thumbnailUrl;
/**
* @public {Error|undefined}
*/
this.thumbnailUrlError;
/** /**
* @public {number|undefined} * @public {number|undefined}
*/ */
this.imageWidth; this.imageWidth;
/**
* @public {Error|undefined}
*/
this.imageWidthError;
/** /**
* @public {number|undefined} * @public {number|undefined}
*/ */
this.imageHeight; this.imageHeight;
/**
* @public {Error|undefined}
*/
this.imageHeightError;
/** /**
* @public {number|undefined} * @public {number|undefined}
*/ */
this.imageRotation; this.imageRotation;
/**
* @public {Error|undefined}
*/
this.imageRotationError;
/** /**
* Thumbnail obtained from content provider. * Thumbnail obtained from content provider.
* @public {string|undefined} * @public {string|undefined}
*/ */
this.contentThumbnailUrl; this.contentThumbnailUrl;
/**
* @public {Error|undefined}
*/
this.contentThumbnailUrlError;
/** /**
* Thumbnail transformation obtained from content provider. * Thumbnail transformation obtained from content provider.
* @public {!ImageTransformation|undefined} * @public {!ImageTransformation|undefined}
*/ */
this.contentThumbnailTransform; this.contentThumbnailTransform;
/**
* @public {Error|undefined}
*/
this.contentThumbnailTransformError;
/** /**
* Image transformation obtained from content provider. * Image transformation obtained from content provider.
* @public {!ImageTransformation|undefined} * @public {!ImageTransformation|undefined}
*/ */
this.contentImageTransform; this.contentImageTransform;
/**
* @public {Error|undefined}
*/
this.contentImageTransformError;
/** /**
* Whether the entry is pinned for ensuring it is available offline. * Whether the entry is pinned for ensuring it is available offline.
* @public {boolean|undefined} * @public {boolean|undefined}
*/ */
this.pinned; this.pinned;
/**
* @public {Error|undefined}
*/
this.pinnedError;
/** /**
* Whether the entry is cached locally. * Whether the entry is cached locally.
* @public {boolean|undefined} * @public {boolean|undefined}
*/ */
this.present; this.present;
/**
* @public {Error|undefined}
*/
this.presentError;
/** /**
* Whether the entry is hosted document of google drive. * Whether the entry is hosted document of google drive.
* @public {boolean|undefined} * @public {boolean|undefined}
*/ */
this.hosted; this.hosted;
/**
* @public {Error|undefined}
*/
this.hostedError;
/** /**
* Whether the entry is modified locally and not synched yet. * Whether the entry is modified locally and not synched yet.
* @public {boolean|undefined} * @public {boolean|undefined}
*/ */
this.dirty; this.dirty;
/**
* @public {Error|undefined}
*/
this.dirtyError;
/** /**
* Whether the entry is present or hosted; * Whether the entry is present or hosted;
* @public {boolean|undefined} * @public {boolean|undefined}
*/ */
this.availableOffline; this.availableOffline;
/**
* @public {Error|undefined}
*/
this.availableOfflineError;
/** /**
* @public {boolean|undefined} * @public {boolean|undefined}
*/ */
this.availableWhenMetered; this.availableWhenMetered;
/**
* @public {Error|undefined}
*/
this.availableWhenMeteredError;
/** /**
* @public {string|undefined} * @public {string|undefined}
*/ */
this.customIconUrl; this.customIconUrl;
/**
* @public {Error|undefined}
*/
this.customIconUrlError;
/** /**
* @public {string|undefined} * @public {string|undefined}
*/ */
this.contentMimeType; this.contentMimeType;
/**
* @public {Error|undefined}
*/
this.contentMimeTypeError;
/** /**
* Whether the entry is shared explicitly with me. * Whether the entry is shared explicitly with me.
* @public {boolean|undefined} * @public {boolean|undefined}
*/ */
this.sharedWithMe; this.sharedWithMe;
/**
* @public {Error|undefined}
*/
this.sharedWithMeError;
/** /**
* Whether the entry is shared publicly. * Whether the entry is shared publicly.
* @public {boolean|undefined} * @public {boolean|undefined}
*/ */
this.shared; this.shared;
/**
* @public {Error|undefined}
*/
this.sharedError;
/** /**
* URL for open a file in browser tab. * URL for open a file in browser tab.
* @public {string|undefined} * @public {string|undefined}
*/ */
this.externalFileUrl; this.externalFileUrl;
/**
* @public {Error|undefined}
*/
this.externalFileUrlError;
/** /**
* @public {string|undefined} * @public {string|undefined}
*/ */
this.mediaTitle; this.mediaTitle;
/**
* @public {Error|undefined}
*/
this.mediaTitleError;
/** /**
* @public {string|undefined} * @public {string|undefined}
*/ */
this.mediaArtist; this.mediaArtist;
/**
* @public {Error|undefined}
*/
this.mediaArtistError;
/** /**
* Mime type obtained by content provider based on URL. * Mime type obtained by content provider based on URL.
* TODO(hirono): Remove the mediaMimeType. * TODO(hirono): Remove the mediaMimeType.
...@@ -146,14 +257,29 @@ function MetadataItem() { ...@@ -146,14 +257,29 @@ function MetadataItem() {
*/ */
this.mediaMimeType; this.mediaMimeType;
/**
* @public {Error|undefined}
*/
this.mediaMimeTypeError;
/** /**
* "Image File Directory" obtained from EXIF header. * "Image File Directory" obtained from EXIF header.
* @public {!Object|undefined} * @public {!Object|undefined}
*/ */
this.ifd; this.ifd;
/**
* @public {Error|undefined}
*/
this.ifdError;
/** /**
* @public {boolean|undefined} * @public {boolean|undefined}
*/ */
this.exifLittleEndian; this.exifLittleEndian;
/**
* @public {Error|undefined}
*/
this.exifLittleEndianError;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment