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: error type enhancement #1478

Merged
merged 12 commits into from
Jan 25, 2024
19 changes: 16 additions & 3 deletions src/dash-playlist-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,10 @@ export default class DashPlaylistLoader extends EventTarget {
message: 'DASH request error at URL: ' + request.uri,
response: request.response,
// MEDIA_ERR_NETWORK
code: 2
code: 2,
metadata: {
errorType: err.errorType
}
};
if (startingState) {
this.state = startingState;
Expand Down Expand Up @@ -400,6 +403,10 @@ export default class DashPlaylistLoader extends EventTarget {
try {
sidx = parseSidx(toUint8(request.response).subarray(8));
} catch (e) {
e.metadata = {
errorType: videojs.Errors.DashManifestSidxParsingError
};

// sidx parsing failed.
this.requestErrored_(e, request, startingState);
return;
Expand All @@ -421,17 +428,23 @@ export default class DashPlaylistLoader extends EventTarget {
}

if (!container || container !== 'mp4') {
const sidxContainer = container || 'unknown';

return fin({
status: request.status,
message: `Unsupported ${container || 'unknown'} container type for sidx segment at URL: ${uri}`,
message: `Unsupported ${sidxContainer} container type for sidx segment at URL: ${uri}`,
// response is just bytes in this case
// but we really don't want to return that.
response: '',
playlist,
internal: true,
playlistExclusionDuration: Infinity,
// MEDIA_ERR_NETWORK
code: 2
code: 2,
metadata: {
errorType: videojs.Errors.UnsupportedSidxContainer,
sidxContainer
}
}, request);
}

Expand Down
10 changes: 8 additions & 2 deletions src/media-segment-request.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import videojs from 'video.js';
import { createTransferableMessage } from './bin-utils';
import { stringToArrayBuffer } from './util/string-to-array-buffer';
import { transmux } from './segment-transmuxer';
Expand Down Expand Up @@ -159,11 +160,16 @@ const parseInitSegment = (segment, callback) => {
// only know how to parse mp4 init segments at the moment
if (type !== 'mp4') {
const uri = segment.map.resolvedUri || segment.map.uri;
const mediaType = type || 'unknown';

return callback({
internal: true,
message: `Found unsupported ${type || 'unknown'} container for initialization segment at URL: ${uri}`,
code: REQUEST_ERRORS.FAILURE
message: `Found unsupported ${mediaType} container for initialization segment at URL: ${uri}`,
code: REQUEST_ERRORS.FAILURE,
metadata: {
errorType: videojs.Errors.UnsupportedMediaInitialization,
mediaType
}
});
}

Expand Down
10 changes: 8 additions & 2 deletions src/playlist-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,10 @@ export default class PlaylistLoader extends EventTarget {
status: xhr.status,
message: `HLS playlist request error at URL: ${uri}.`,
responseText: xhr.responseText,
code: (xhr.status >= 500) ? 4 : 2
code: (xhr.status >= 500) ? 4 : 2,
metadata: {
errorType: videojs.Errors.HlsPlaylistRequestError
}
};

this.trigger('error');
Expand Down Expand Up @@ -851,7 +854,10 @@ export default class PlaylistLoader extends EventTarget {
message: `HLS playlist request error at URL: ${this.src}.`,
responseText: req.responseText,
// MEDIA_ERR_NETWORK
code: 2
code: 2,
metadata: {
errorType: videojs.Errors.HlsPlaylistRequestError
}
};
if (this.state === 'HAVE_NOTHING') {
this.started = false;
Expand Down
37 changes: 26 additions & 11 deletions src/segment-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -819,15 +819,21 @@ export default class SegmentLoader extends videojs.EventTarget {
* set an error on the segment loader and null out any pending segements
*
* @param {Error} error the error to set on the SegmentLoader
* @param {boolean} isAppendError a flag to trigger the `appendError` event.
* @return {Error} the error that was set or that is currently set
*/
error(error) {
error(error, isAppendError = false) {
if (typeof error !== 'undefined') {
this.logger_('error occurred:', error);
this.error_ = error;
}

this.pendingSegment_ = null;

const errorEvent = isAppendError ? 'appendError' : 'error';

this.trigger(errorEvent);

return this.error_;
}

Expand Down Expand Up @@ -2277,9 +2283,11 @@ export default class SegmentLoader extends videojs.EventTarget {
`video buffer: ${timeRangesToArray(videoBuffered).join(', ')}, `);
this.error({
message: 'Quota exceeded error with append of a single segment of content',
excludeUntil: Infinity
excludeUntil: Infinity,
metadata: {
errorType: videojs.Errors.SegmentExceedsSourceBufferQuota
}
});
this.trigger('error');
return;
}

Expand Down Expand Up @@ -2332,15 +2340,19 @@ export default class SegmentLoader extends videojs.EventTarget {
}

this.logger_('Received non QUOTA_EXCEEDED_ERR on append', error);
this.error(`${type} append of ${bytes.length}b failed for segment ` +
`#${segmentInfo.mediaIndex} in playlist ${segmentInfo.playlist.id}`);

// If an append errors, we often can't recover.
// (see https://w3c.github.io/media-source/#sourcebuffer-append-error).
//
// Trigger a special error so that it can be handled separately from normal,
// recoverable errors.
this.trigger('appenderror');
this.error({
message: `${type} append of ${bytes.length}b failed for segment ` +
`#${segmentInfo.mediaIndex} in playlist ${segmentInfo.playlist.id}`,
metadata: {
errorType: videojs.Errors.SegmentAppendError
}
}, true);
}

appendToSourceBuffer_({ segmentInfo, type, initSegment, data, bytes }) {
Expand Down Expand Up @@ -2714,7 +2726,6 @@ export default class SegmentLoader extends videojs.EventTarget {
// emit an error event to exclude the current playlist
this.mediaRequestsErrored += 1;
this.error(error);
this.trigger('error');
return;
}

Expand Down Expand Up @@ -2820,9 +2831,11 @@ export default class SegmentLoader extends videojs.EventTarget {
if (!trackInfo) {
this.error({
message: 'No starting media returned, likely due to an unsupported media format.',
playlistExclusionDuration: Infinity
playlistExclusionDuration: Infinity,
metadata: {
errorType: videojs.Errors.SegmentUnsupportedMediaFormat
}
});
this.trigger('error');
return;
}
// Although transmuxing is done, appends may not yet be finished. Throw a marker
Expand Down Expand Up @@ -2901,9 +2914,11 @@ export default class SegmentLoader extends videojs.EventTarget {
if (illegalMediaSwitchError) {
this.error({
message: illegalMediaSwitchError,
playlistExclusionDuration: Infinity
playlistExclusionDuration: Infinity,
metadata: {
errorType: videojs.Errors.SegmentSwitchError
}
});
this.trigger('error');
return true;
}

Expand Down
5 changes: 4 additions & 1 deletion src/videojs-http-streaming.js
Original file line number Diff line number Diff line change
Expand Up @@ -1078,7 +1078,10 @@ class VhsHandler extends Component {
this.logger_('error while creating EME key session', err);
this.player_.error({
message: 'Failed to initialize media keys for EME',
code: 3
code: 3,
metadata: {
errorType: videojs.Errors.EMEKeySessionCreationError
}
});
});
}
Expand Down
12 changes: 10 additions & 2 deletions src/vtt-segment-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,12 @@ export default class VTTSegmentLoader extends SegmentLoader {
this.loadVttJs()
.then(
() => this.segmentRequestFinished_(error, simpleSegment, result),
() => this.stopForError({ message: 'Error loading vtt.js' })
() => this.stopForError({
message: 'Error loading vtt.js',
metadata: {
errorType: videojs.Errors.VttLoadError
}
})
);
return;
}
Expand All @@ -325,7 +330,10 @@ export default class VTTSegmentLoader extends SegmentLoader {
this.parseVTTCues_(segmentInfo);
} catch (e) {
this.stopForError({
message: e.message
message: e.message,
metadata: {
errorType: videojs.Errors.VttCueParsingError
}
});
return;
}
Expand Down
Loading