Skip to content

Commit

Permalink
@misteroneill fixed wrapping native and emulated MediaErrors. closes v…
Browse files Browse the repository at this point in the history
  • Loading branch information
misteroneill authored and gkatsev committed Aug 24, 2016
1 parent 13d16c1 commit b56ed61
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 22 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ CHANGELOG
=========

## HEAD (Unreleased)
_(none)_
* @misteroneill fixed wrapping native and emulated MediaErrors ([view](https://github.com/videojs/video.js/pull/3562))

--------------------

Expand Down
41 changes: 31 additions & 10 deletions src/js/media-error.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,45 @@
import assign from 'object.assign';

/*
* Custom MediaError to mimic the HTML5 MediaError
* Custom MediaError class which mimics the standard HTML5 MediaError class.
*
* @param {Number} code The media error code
* @param {Number|String|Object|MediaError} value
* This can be of multiple types:
* - Number: should be a standard error code
* - String: an error message (the code will be 0)
* - Object: arbitrary properties
* - MediaError (native): used to populate a video.js MediaError object
* - MediaError (video.js): will return itself if it's already a
* video.js MediaError object.
*/
let MediaError = function(code){
if (typeof code === 'number') {
this.code = code;
} else if (typeof code === 'string') {
function MediaError(value) {

// Allow redundant calls to this constructor to avoid having `instanceof`
// checks peppered around the code.
if (value instanceof MediaError) {
return value;
}

if (typeof value === 'number') {
this.code = value;
} else if (typeof value === 'string') {
// default code is zero, so this is a custom error
this.message = code;
} else if (typeof code === 'object') { // object
assign(this, code);
this.message = value;
} else if (typeof value === 'object') {

// We assign the `code` property manually because native MediaError objects
// do not expose it as an own/enumerable property of the object.
if (typeof value.code === 'number') {
this.code = value.code;
}

assign(this, value);
}

if (!this.message) {
this.message = MediaError.defaultMessages[this.code] || '';
}
};
}

/*
* The error code that refers two one of the defined
Expand Down
7 changes: 1 addition & 6 deletions src/js/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -2277,12 +2277,7 @@ class Player extends Component {
return this;
}

// error instance
if (err instanceof MediaError) {
this.error_ = err;
} else {
this.error_ = new MediaError(err);
}
this.error_ = new MediaError(err);

// add the vjs-error classname to the player
this.addClass('vjs-error');
Expand Down
6 changes: 1 addition & 5 deletions src/js/tech/tech.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,7 @@ class Tech extends Component {
*/
error(err) {
if (err !== undefined) {
if (err instanceof MediaError) {
this.error_ = err;
} else {
this.error_ = new MediaError(err);
}
this.error_ = new MediaError(err);
this.trigger('error');
}
return this.error_;
Expand Down
65 changes: 65 additions & 0 deletions test/unit/media-error.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/* eslint-env qunit */
import window from 'global/window';
import MediaError from '../../src/js/media-error';

/**
* Creates a real native MediaError object.
*
* @param {Number} code
* @param {String} [message]
* @return {MediaError}
*/
const createNativeMediaError = (code, message) => {
const err = Object.create(window.MediaError);

Object.defineProperty(err, 'code', {value: code});

if (message) {
err.message = message;
}

return err;
};

QUnit.module('MediaError');

QUnit.test('can be constructed from a number', function(assert) {
const mediaError = new MediaError(1);

assert.strictEqual(mediaError.code, 1);
assert.strictEqual(mediaError.message, MediaError.defaultMessages['1']);
});

QUnit.test('can be constructed from a string', function(assert) {
const mediaError = new MediaError('hello, world');

assert.strictEqual(mediaError.code, 0);
assert.strictEqual(mediaError.message, 'hello, world');
});

QUnit.test('can be constructed from an object', function(assert) {
const mediaError = new MediaError({code: 2});
const mediaErrorMsg = new MediaError({code: 2, message: 'hello, world'});

assert.strictEqual(mediaError.code, 2);
assert.strictEqual(mediaError.message, MediaError.defaultMessages['2']);
assert.strictEqual(mediaErrorMsg.code, 2);
assert.strictEqual(mediaErrorMsg.message, 'hello, world');
});

QUnit.test('can be constructed from a native MediaError object', function(assert) {
const mediaError = new MediaError(createNativeMediaError(3));
const mediaErrorMsg = new MediaError(createNativeMediaError(4, 'hello, world'));

assert.strictEqual(mediaError.code, 3);
assert.strictEqual(mediaError.message, MediaError.defaultMessages['3']);
assert.strictEqual(mediaErrorMsg.code, 4);
assert.strictEqual(mediaErrorMsg.message, 'hello, world');
});

QUnit.test('can be constructed redundantly', function(assert) {
const mediaError = new MediaError(2);
const redundantMediaError = new MediaError(mediaError);

assert.strictEqual(redundantMediaError, mediaError);
});

0 comments on commit b56ed61

Please sign in to comment.