Skip to content

Commit

Permalink
Add an indicator for critical errors.
Browse files Browse the repository at this point in the history
This adds a severity field to Error objects.  This can be used to
detect whether an error is recoverable.  All the same errors are still
reported so the field can be ignored.

There are two possible values:
* RECOVERABLE means that the Player will try to recover from the error
* CRITICAL means the Player will be unable to continue and must call
  load() again

Closes #564

Change-Id: Ie2c5468340c13e7a288b99690ab65b7ecc0a6b29
  • Loading branch information
TheModMaker committed Apr 4, 2017
1 parent 46160f5 commit 575f2ad
Show file tree
Hide file tree
Showing 59 changed files with 323 additions and 30 deletions.
1 change: 1 addition & 0 deletions lib/abr/simple_abr_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ shaka.abr.SimpleAbrManager.prototype.chooseVariant_ = function(variants) {

if (variants.length && !sortedVariants.length) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.RESTRICTIONS_CANNOT_BE_MET);
}
Expand Down
7 changes: 6 additions & 1 deletion lib/cast/cast_sender.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,16 +216,19 @@ shaka.cast.CastSender.prototype.setAppData = function(appData) {
shaka.cast.CastSender.prototype.cast = function(initState) {
if (!this.apiReady_) {
return Promise.reject(new shaka.util.Error(
shaka.util.Error.Severity.RECOVERABLE,
shaka.util.Error.Category.CAST,
shaka.util.Error.Code.CAST_API_UNAVAILABLE));
}
if (!this.hasReceivers_) {
return Promise.reject(new shaka.util.Error(
shaka.util.Error.Severity.RECOVERABLE,
shaka.util.Error.Category.CAST,
shaka.util.Error.Code.NO_CAST_RECEIVERS));
}
if (this.isCasting_) {
return Promise.reject(new shaka.util.Error(
shaka.util.Error.Severity.RECOVERABLE,
shaka.util.Error.Category.CAST,
shaka.util.Error.Code.ALREADY_CASTING));
}
Expand Down Expand Up @@ -362,6 +365,7 @@ shaka.cast.CastSender.prototype.onConnectionError_ = function(error) {
}

this.castPromise_.reject(new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.CAST,
code,
error));
Expand Down Expand Up @@ -509,6 +513,7 @@ shaka.cast.CastSender.prototype.rejectAllPromises_ = function() {
// At the moment, load() is the only async operation we are worried
// about.
p.reject(new shaka.util.Error(
shaka.util.Error.Severity.RECOVERABLE,
shaka.util.Error.Category.PLAYER,
shaka.util.Error.Code.LOAD_INTERRUPTED));
}
Expand Down Expand Up @@ -555,7 +560,7 @@ shaka.cast.CastSender.prototype.onMessageReceived_ =
if (error) {
// This is a hacky way to reconstruct the serialized error.
var reconstructedError = new shaka.util.Error(
error.category, error.code);
error.severity, error.category, error.code);
for (var k in error) {
(/** @type {Object} */(reconstructedError))[k] = error[k];
}
Expand Down
5 changes: 4 additions & 1 deletion lib/dash/content_protection.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ shaka.dash.ContentProtection.parseFromAdaptationSet = function(
defaultKeyId = keyIds[0];
if (keyIds.some(Functional.isNotEqualFunc(defaultKeyId))) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_CONFLICTING_KEY_IDS);
}
Expand Down Expand Up @@ -232,6 +233,7 @@ shaka.dash.ContentProtection.parseFromRepresentation = function(
// If we have filtered out all key-systems, throw an error.
if (context.drmInfos.length == 0) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_NO_COMMON_KEY_SYSTEM);
}
Expand Down Expand Up @@ -311,6 +313,7 @@ shaka.dash.ContentProtection.parseElements_ = function(elems) {
keyId = keyId.replace(/-/g, '').toLowerCase();
if (keyId.indexOf(' ') >= 0) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_MULTIPLE_KEY_IDS_NOT_SUPPORTED);
}
Expand All @@ -329,8 +332,8 @@ shaka.dash.ContentProtection.parseElements_ = function(elems) {
return ret;
});
} catch (e) {
// Invalid PSSH data, ignore.
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_PSSH_BAD_ENCODING);
}
Expand Down
10 changes: 9 additions & 1 deletion lib/dash/dash_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,9 @@ shaka.dash.DashParser.prototype.parseManifest_ =
mpd = xml.documentElement;
}
if (!mpd) {
throw new Error(Error.Category.MANIFEST, Error.Code.DASH_INVALID_XML);
throw new Error(
Error.Severity.CRITICAL, Error.Category.MANIFEST,
Error.Code.DASH_INVALID_XML);
}

// Get any Location elements. This will update the manifest location and
Expand Down Expand Up @@ -691,6 +693,7 @@ shaka.dash.DashParser.prototype.parsePeriod_ = function(
var uniqueRepIds = representationIds.filter(Functional.isNotDuplicate);
if (context.dynamic && representationIds.length != uniqueRepIds.length) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_DUPLICATE_REPRESENTATION_ID);
}
Expand Down Expand Up @@ -721,6 +724,7 @@ shaka.dash.DashParser.prototype.parsePeriod_ = function(

if (!videoSets.length && !audioSets.length) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_EMPTY_PERIOD);
}
Expand Down Expand Up @@ -942,6 +946,7 @@ shaka.dash.DashParser.prototype.parseAdaptationSet_ = function(context, elem) {

if (streams.length == 0) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_EMPTY_ADAPTATION_SET);
}
Expand Down Expand Up @@ -1118,7 +1123,10 @@ shaka.dash.DashParser.prototype.onUpdate_ = function() {

// Try updating again, but ensure we haven't been destroyed.
if (this.playerInterface_) {
// We will retry updating, so override the severity of the error.
error.severity = shaka.util.Error.Severity.RECOVERABLE;
this.playerInterface_.onError(error);

this.setUpdateTimer_(0);
}
}.bind(this));
Expand Down
3 changes: 3 additions & 0 deletions lib/dash/segment_base.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ shaka.dash.SegmentBase.createSegmentIndex_ = function(
'SegmentBase specifies an unsupported container type.',
context.representation);
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_UNSUPPORTED_CONTAINER);
}
Expand All @@ -230,6 +231,7 @@ shaka.dash.SegmentBase.createSegmentIndex_ = function(
'but does not contain an Initialization element.',
context.representation);
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_WEBM_MISSING_INIT);
}
Expand Down Expand Up @@ -259,6 +261,7 @@ shaka.dash.SegmentBase.createSegmentIndex_ = function(
'or a RepresentationIndex element.',
context.representation);
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_NO_SEGMENT_INFO);
}
Expand Down
3 changes: 3 additions & 0 deletions lib/dash/segment_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ shaka.dash.SegmentList.checkSegmentListInfo_ = function(context, info) {
'but does not specify a segment duration or timeline.',
context.representation);
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_NO_SEGMENT_INFO);
}
Expand All @@ -220,6 +221,7 @@ shaka.dash.SegmentList.checkSegmentListInfo_ = function(context, info) {
'or timeline.',
context.representation);
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_NO_SEGMENT_INFO);
}
Expand All @@ -230,6 +232,7 @@ shaka.dash.SegmentList.checkSegmentListInfo_ = function(context, info) {
'the SegmentList has an empty timeline.',
context.representation);
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_NO_SEGMENT_INFO);
}
Expand Down
4 changes: 4 additions & 0 deletions lib/dash/segment_template.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ shaka.dash.SegmentTemplate.checkSegmentTemplateInfo_ = function(context, info) {
'a SegmentTimeline, or a segment duration.',
context.representation);
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_NO_SEGMENT_INFO);
} else if (n != 1) {
Expand All @@ -233,6 +234,7 @@ shaka.dash.SegmentTemplate.checkSegmentTemplateInfo_ = function(context, info) {
'the SegmentTemplate\'s media URL template is missing.',
context.representation);
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_NO_SEGMENT_INFO);
}
Expand Down Expand Up @@ -262,6 +264,7 @@ shaka.dash.SegmentTemplate.createFromIndexTemplate_ = function(
'SegmentTemplate specifies an unsupported container type.',
context.representation);
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_UNSUPPORTED_CONTAINER);
}
Expand All @@ -273,6 +276,7 @@ shaka.dash.SegmentTemplate.createFromIndexTemplate_ = function(
'but does not contain an initialization URL template.',
context.representation);
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.DASH_WEBM_MISSING_INIT);
}
Expand Down
8 changes: 8 additions & 0 deletions lib/hls/hls_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ shaka.hls.HlsParser.prototype.parseManifest_ = function(data, uri) {
// See error code for details.
if (playlist.type != shaka.hls.PlaylistType.MASTER) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.HLS_MASTER_PLAYLIST_NOT_PROVIDED);
}
Expand Down Expand Up @@ -528,6 +529,7 @@ shaka.hls.HlsParser.prototype.createStreamInfo_ =
if (playlist.type != shaka.hls.PlaylistType.MEDIA) {
// EXT-X-MEDIA tags should point to media playlists.
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.HLS_INVALID_PLAYLIST_HIERARCHY);
}
Expand Down Expand Up @@ -604,6 +606,7 @@ shaka.hls.HlsParser.prototype.createStreamInfo_ =

if (encrypted && !drmInfos.length) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.HLS_KEYFORMATS_NOT_SUPPORTED);
}
Expand Down Expand Up @@ -659,6 +662,7 @@ shaka.hls.HlsParser.prototype.createInitSegmentReference_ = function(playlist) {
return null;
} else if (mapTags.length > 1) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.HLS_MULTIPLE_MEDIA_INIT_SECTIONS_FOUND);
}
Expand Down Expand Up @@ -808,6 +812,7 @@ shaka.hls.HlsParser.prototype.guessCodecs_ = function(contentType, codecs) {

// Unable to guess codecs.
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.HLS_COULD_NOT_GUESS_CODECS,
codecs);
Expand Down Expand Up @@ -841,6 +846,7 @@ shaka.hls.HlsParser.prototype.guessMimeType_ = function(contentType, uri) {
var mimeType = map[extension];
if (!mimeType) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.HLS_COULD_NOT_GUESS_MIME_TYPE,
extension);
Expand Down Expand Up @@ -886,6 +892,7 @@ shaka.hls.HlsParser.getRequiredAttributeValue_ =
var attribute = tag.getAttribute(attributeName);
if (!attribute) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.HLS_REQUIRED_ATTRIBUTE_MISSING,
attributeName);
Expand All @@ -910,6 +917,7 @@ shaka.hls.HlsParser.prototype.getRequiredTag_ = function(tags, tagName) {
var tag = Utils.getFirstTagWithName(tags, tagName);
if (!tag) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.HLS_REQUIRED_TAG_MISSING, tagName);
}
Expand Down
3 changes: 3 additions & 0 deletions lib/hls/manifest_text_parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ shaka.hls.ManifestTextParser.prototype.parsePlaylist = function(data, uri) {

if (!/^#EXTM3U($|[ \t\n])/m.test(lines[0])) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.HLS_PLAYLIST_HEADER_MISSING);
}
Expand Down Expand Up @@ -83,6 +84,7 @@ shaka.hls.ManifestTextParser.prototype.parsePlaylist = function(data, uri) {
if (playlistType != shaka.hls.PlaylistType.MEDIA) {
// Only media playlist should contain segment tags
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.HLS_INVALID_PLAYLIST_HIERARCHY);
}
Expand Down Expand Up @@ -172,6 +174,7 @@ shaka.hls.ManifestTextParser.parseTag = function(id, word) {
var blocks = word.match(/^#(EXT[^:]*)(?::(.*))?$/);
if (!blocks) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
shaka.util.Error.Category.MANIFEST,
shaka.util.Error.Code.INVALID_HLS_TAG);
}
Expand Down
Loading

0 comments on commit 575f2ad

Please sign in to comment.