Added missing named errors to kurento adapter, appended transaction info to thrown errors on mcs-core and some cleanup

This commit is contained in:
prlanzarin 2018-07-18 16:24:08 +00:00
parent d70cd35f1d
commit f61102940e
10 changed files with 164 additions and 237 deletions

View File

@ -37,10 +37,9 @@ module.exports = class MediaServer extends EventEmitter {
}
resolve();
}
catch (err) {
this._handleError(err);
catch (error) {
this.emit(C.ERROR.MEDIA_SERVER_OFFLINE);
reject(err);
reject(this._handleError(error));
}
});
}
@ -49,8 +48,7 @@ module.exports = class MediaServer extends EventEmitter {
return new Promise((resolve, reject) => {
mediaServerClient(serverUri, {failAfter: 1}, (error, client) => {
if (error) {
error = this._handleError(error);
return reject(error);
return reject(this._handleError(error));
}
resolve(client);
});
@ -131,16 +129,15 @@ module.exports = class MediaServer extends EventEmitter {
if (pipeline && typeof pipeline.release === 'function') {
pipeline.release((error) => {
if (error) {
error = this._handleError(error);
return reject(error);
return reject(this._handleError(error));
}
delete this._mediaPipelines[room];
return resolve()
});
}
}
catch (err) {
return reject(this._handleError(err));
catch (error) {
return reject(this._handleError(error));
}
});
}
@ -150,8 +147,7 @@ module.exports = class MediaServer extends EventEmitter {
try {
pipeline.create(type, options, (error, mediaElement) => {
if (error) {
error = this._handleError(error);
return reject(error);
return reject(this._handleError(error));
}
Logger.info("[mcs-media] Created [" + type + "] media element: " + mediaElement.id);
this._mediaElements[mediaElement.id] = mediaElement;
@ -187,7 +183,7 @@ module.exports = class MediaServer extends EventEmitter {
const source = this._mediaElements[sourceId];
return new Promise((resolve, reject) => {
if (source == null) {
return reject(this._handleError("[mcs-recording] startRecording error"));
return reject(this._handleError(ERRORS[40101]));
}
try {
source.record((err) => {
@ -208,7 +204,7 @@ module.exports = class MediaServer extends EventEmitter {
return new Promise((resolve, reject) => {
if (source == null) {
return reject(this._handleError("[mcs-recording] stopRecording error"));
return reject(this._handleError(ERRORS[40101]));
}
try {
source.stopAndWait((err) => {
@ -230,15 +226,14 @@ module.exports = class MediaServer extends EventEmitter {
return new Promise((resolve, reject) => {
if (source == null || sink == null) {
return reject(this._handleError("[mcs-media] Failed to connect " + type + ": " + sourceId + " to " + sinkId));
return reject(this._handleError(ERRORS[40101]));
}
try {
switch (type) {
case 'ALL':
source.connect(sink, (error) => {
if (error) {
error = this._handleError(error);
return reject(error);
return reject(this._handleError(error));
}
return resolve();
});
@ -248,8 +243,7 @@ module.exports = class MediaServer extends EventEmitter {
case 'AUDIO':
source.connect(sink, 'AUDIO', (error) => {
if (error) {
error = this._handleError(error);
return reject(error);
return reject(this._handleError(error));
}
return resolve();
});
@ -257,19 +251,18 @@ module.exports = class MediaServer extends EventEmitter {
case 'VIDEO':
source.connect(sink, (error) => {
if (error) {
error = this._handleError(error);
return reject(error);
return reject(this._handleError(error));
}
return resolve();
});
break;
default:
return reject(this._handleError("[mcs-media] Invalid connect type"));
return reject(this._handleError(ERRORS[40107]));
}
}
catch (err) {
return reject(this._handleError(err));
catch (error) {
return reject(this._handleError(error));
}
});
}
@ -280,7 +273,7 @@ module.exports = class MediaServer extends EventEmitter {
return new Promise((resolve, reject) => {
if (source == null || sink == null) {
return reject(this._handleError("[mcs-media] Failed to disconnect " + type + ": " + sourceId + " to " + sinkId));
return reject(this._handleError(ERRORS[40101]));
}
try {
switch (type) {
@ -311,11 +304,11 @@ module.exports = class MediaServer extends EventEmitter {
break;
default:
return reject(this._handleError("[mcs-media] Invalid disconnect type"));
return reject(this._handleError(ERRORS[40107]));
}
}
catch (err) {
return reject(this._handleError(err));
catch (error) {
return reject(this._handleError(error));
}
});
}
@ -369,20 +362,18 @@ module.exports = class MediaServer extends EventEmitter {
if (mediaElement && candidate) {
mediaElement.addIceCandidate(candidate, (error) => {
if (error) {
error = this._handleError(error);
return reject(error);
return reject(this._handleError(error));
}
Logger.debug("[mcs-media] Added ICE candidate for => " + elementId);
return resolve();
});
}
else {
return reject("Candidate could not be parsed or media element does not exist");
return reject(this._handleError(ERRORS[40101]));
}
}
catch (err) {
err = this._handleError(err);
reject(err);
catch (error) {
return reject(this._handleError(error));
}
});
}
@ -394,7 +385,7 @@ module.exports = class MediaServer extends EventEmitter {
return new Promise((resolve, reject) => {
try {
if (mediaElement == null) {
return reject("[mcs-media] There is no element " + elementId);
return reject(this._handleError(ERRORS[40101]));
}
mediaElement.gatherCandidates((error) => {
if (error) {
@ -457,7 +448,7 @@ module.exports = class MediaServer extends EventEmitter {
});
}
else {
return reject(this._handleError("[mcs-media] There is no element " + elementId));
return reject(this._handleError(ERRORS[40101]));
}
}
catch (err) {
@ -544,39 +535,44 @@ module.exports = class MediaServer extends EventEmitter {
}
_handleError(err) {
let { message, code, stack, data, reason } = err;
let { message: oldMessage , code, stack } = err;
let message;
if (code && code >= C.ERROR.MIN_CODE && code <= C.ERROR.MAX_CODE) {
return err;
}
const error = ERRORS[code]? ERRORS[code].error : null;
console.log("BYE", error);
if (error == null) {
switch (message) {
switch (oldMessage) {
case "Request has timed out":
({ code, reason } = C.ERROR.MEDIA_SERVER_REQUEST_TIMEOUT);
({ code, message } = C.ERROR.MEDIA_SERVER_REQUEST_TIMEOUT);
break;
case "Connection error":
({ code, reason } = C.ERROR.CONNECTION_ERROR);
({ code, message } = C.ERROR.CONNECTION_ERROR);
break;
default:
({ code, reason } = C.ERROR.MEDIA_SERVER_GENERIC_ERROR);
({ code, message } = C.ERROR.MEDIA_SERVER_GENERIC_ERROR);
}
}
else {
({ code, reason } = error);
({ code, message } = error);
}
// Checking if the error needs to be wrapped into a JS Error instance
if (!isError(err)) {
err = new Error(reason);
err = new Error(message);
}
err.code = code;
err.message = reason;
err.details = message;
err.message = message;
err.details = oldMessage;
err.stack = stack
Logger.debug('[mcs-media] Media Server returned an', err.code, err.message, err.stack);
Logger.debug('[mcs-media] Media Server returned an', err.code, err.message);
Logger.trace(err.stack);
return err;
}

View File

@ -47,30 +47,32 @@ exports.EVENT.RECORDING.PAUSED = 'Paused';
// Error codes
exports.ERROR = {};
exports.ERROR.CONNECTION_ERROR = { code: 2000, reason: "MEDIA_SERVER_CONNECTION_ERROR" };
exports.ERROR.MEDIA_SERVER_OFFLINE = { code: 2001, reason: "MEDIA_SERVER_OFFLINE" };
exports.ERROR.MEDIA_SERVER_NO_RESOURCES = { code: 2002, reason: "MEDIA_SERVER_NO_RESOURCES" };
exports.ERROR.ICE_CANDIDATE_FAILED = { code: 2003, reason: "ICE_ADD_CANDIDATE_FAILED" };
exports.ERROR.ICE_GATHERING_FAILED = { code: 2004, reason: "ICE_GATHERING_FAILED" };
exports.ERROR.MEDIA_SERVER_REQUEST_TIMEOUT = { code: 2005, reason: "MEDIA_SERVER_REQUEST_TIMEOUT" };
exports.ERROR.MEDIA_SERVER_GENERIC_ERROR = { code: 2006, reason: "MEDIA_SERVER_GENERIC_ERROR" };
exports.ERROR.MIN_CODE = 2000;
exports.ERROR.MAX_CODE = 2999;
exports.ERROR.CONNECTION_ERROR = { code: 2000, message: "MEDIA_SERVER_CONNECTION_ERROR" };
exports.ERROR.MEDIA_SERVER_OFFLINE = { code: 2001, message: "MEDIA_SERVER_OFFLINE" };
exports.ERROR.MEDIA_SERVER_NO_RESOURCES = { code: 2002, message: "MEDIA_SERVER_NO_RESOURCES" };
exports.ERROR.ICE_CANDIDATE_FAILED = { code: 2003, message: "ICE_ADD_CANDIDATE_FAILED" };
exports.ERROR.ICE_GATHERING_FAILED = { code: 2004, message: "ICE_GATHERING_FAILED" };
exports.ERROR.MEDIA_SERVER_REQUEST_TIMEOUT = { code: 2005, message: "MEDIA_SERVER_REQUEST_TIMEOUT" };
exports.ERROR.MEDIA_SERVER_GENERIC_ERROR = { code: 2006, message: "MEDIA_SERVER_GENERIC_ERROR" };
exports.ERROR.ROOM_GENERIC_ERROR = { code: 2100, reason: "ROOM_GENNERIC_ERROR" };
exports.ERROR.ROOM_NOT_FOUND = { code: 2101, reason: "ROOM_NOT_FOUND" };
exports.ERROR.USER_GENERIC_ERROR = { code: 2110, reason: "USER_GENERIC_ERROR" };
exports.ERROR.USER_NOT_FOUND = { code: 2111, reason: "USER_NOT_FOUND" };
exports.ERROR.ROOM_GENERIC_ERROR = { code: 2100, message: "ROOM_GENNERIC_ERROR" };
exports.ERROR.ROOM_NOT_FOUND = { code: 2101, message: "ROOM_NOT_FOUND" };
exports.ERROR.USER_GENERIC_ERROR = { code: 2110, message: "USER_GENERIC_ERROR" };
exports.ERROR.USER_NOT_FOUND = { code: 2111, message: "USER_NOT_FOUND" };
exports.ERROR.MEDIA_GENERIC_ERROR = { code: 2200, reason: "MEDIA_GENERIC_ERROR" };
exports.ERROR.MEDIA_NOT_FOUND = { code: 2201, reason: "MEDIA_NOT_FOUND" };
exports.ERROR.MEDIA_INVALID_SDP = { code: 2202, reason: "MEDIA_INVALID_SDP" };
exports.ERROR.MEDIA_NO_AVAILABLE_CODEC = { code: 2203, reason: "MEDIA_NO_AVAILABLE_CODEC" };
exports.ERROR.MEDIA_INVALID_TYPE = { code: 2204, reason: "MEDIA_INVALID_TYPE" };
exports.ERROR.MEDIA_INVALID_OPERATION = { code: 2205, reason: "MEDIA_INVALID_OPERATION" };
exports.ERROR.MEDIA_PROCESS_OFFER_FAILED = { code: 2206, reason : "MEDIA_PROCESS_OFFER_FAILED" };
exports.ERROR.MEDIA_PROCESS_ANSWER_FAILED = { code: 2207, reason : "MEDIA_PROCESS_ANSWER_FAILED" };
exports.ERROR.MEDIA_GENERIC_PROCESS_ERROR = { code: 2208, reason: "MEDIA_GENERIC_PROCESS_ERROR" };
exports.ERROR.MEDIA_ADAPTER_OBJECT_NOT_FOUND = { code: 2209, reason: "MEDIA_ADAPTER_OBJECT_NOT_FOUND" };
exports.ERROR.MEDIA_CONNECT_ERROR = { code: 2210, reason: "MEDIA_CONNECT_ERROR" };
exports.ERROR.MEDIA_GENERIC_ERROR = { code: 2200, message: "MEDIA_GENERIC_ERROR" };
exports.ERROR.MEDIA_NOT_FOUND = { code: 2201, message: "MEDIA_NOT_FOUND" };
exports.ERROR.MEDIA_INVALID_SDP = { code: 2202, message: "MEDIA_INVALID_SDP" };
exports.ERROR.MEDIA_NO_AVAILABLE_CODEC = { code: 2203, message: "MEDIA_NO_AVAILABLE_CODEC" };
exports.ERROR.MEDIA_INVALID_TYPE = { code: 2204, message: "MEDIA_INVALID_TYPE" };
exports.ERROR.MEDIA_INVALID_OPERATION = { code: 2205, message: "MEDIA_INVALID_OPERATION" };
exports.ERROR.MEDIA_PROCESS_OFFER_FAILED = { code: 2206, message : "MEDIA_PROCESS_OFFER_FAILED" };
exports.ERROR.MEDIA_PROCESS_ANSWER_FAILED = { code: 2207, message : "MEDIA_PROCESS_ANSWER_FAILED" };
exports.ERROR.MEDIA_GENERIC_PROCESS_ERROR = { code: 2208, message: "MEDIA_GENERIC_PROCESS_ERROR" };
exports.ERROR.MEDIA_ADAPTER_OBJECT_NOT_FOUND = { code: 2209, message: "MEDIA_ADAPTER_OBJECT_NOT_FOUND" };
exports.ERROR.MEDIA_CONNECT_ERROR = { code: 2210, message: "MEDIA_CONNECT_ERROR" };

View File

@ -24,55 +24,50 @@ module.exports = class MCSApiStub extends EventEmitter {
async join (room, type, params) {
try {
const answer = await this._mediaController.join(room, type, params);
return Promise.resolve(answer);
return (answer);
}
catch (err) {
Logger.error("[MCSApi] join ", err);
Promise.reject(err);
catch (error) {
throw (this._handleError(error, 'join', { room, type, params}));
}
}
async leave (roomId, userId) {
async leave (room, user) {
try {
const answer = await this._mediaController.leave(roomId, userId);
return Promise.resolve(answer);
const answer = await this._mediaController.leave(room, user);
return (answer);
}
catch (err) {
Logger.error("[MCSApi] leave ", err);
return Promise.reject(err);
catch (error) {
throw (this._handleError(error, 'leave', { room, user }));
}
}
async publishnsubscribe (user, sourceId, sdp, params) {
try {
const answer = await this._mediaController.publishnsubscribe(user, sourceId, sdp, params);
return Promise.resolve(answer);
return (answer);
}
catch (err) {
Logger.error("[MCSApi] publishnsubscribe ", err);
return Promise.reject(err);
catch (error) {
throw (this._handleError(error, 'publishnsubscribe', { user, sourceId, sdp, params }));
}
}
async publish (user, room, type, params) {
try {
const answer = await this._mediaController.publish(user, room, type, params);
return Promise.resolve(answer);
return (answer);
}
catch (err) {
Logger.error("[MCSApi] publish ", err);
return Promise.reject(err);
catch (error) {
throw (this._handleError(error, 'publish', { user, room, type, params }));
}
}
async unpublish (user, mediaId) {
try {
await this._mediaController.unpublish(mediaId);
return Promise.resolve();
return ;
}
catch (err) {
Logger.error("[MCSApi] unpublish ", err);
return Promise.reject(err);
catch (error) {
throw (this._handleError(error, 'unpublish', { user, mediaId }));
}
}
@ -80,66 +75,60 @@ module.exports = class MCSApiStub extends EventEmitter {
try {
const answer = await this._mediaController.subscribe(user, sourceId, type, params);
return Promise.resolve(answer);
return (answer);
}
catch (err) {
Logger.error("[MCSApi] subscribe ", err);
return Promise.reject(err);
catch (error) {
throw (this._handleError(error, 'subscribe', { user, sourceId, type, params }));
}
}
async unsubscribe (user, mediaId) {
try {
await this._mediaController.unsubscribe(user, mediaId);
return Promise.resolve();
return ;
}
catch (err) {
Logger.error("[MCSApi] unsubscribe ", err);
return Promise.reject(err);
catch (error) {
throw (this._handleError(error, 'unsubscribe', { user, mediaId }));
}
}
async startRecording(userId, mediaId, recordingName) {
try {
const answer = await this._mediaController.startRecording(userId, mediaId, recordingName);
return Promise.resolve(answer);
return (answer);
}
catch (err) {
Logger.error("[MCSApi] startRecording ", err);
return Promise.reject(err);
catch (error) {
throw (this._handleError(error, 'startRecording', { userId, mediaId, recordingName }));
}
}
async stopRecording(userId, sourceId, recId) {
try {
let answer = await this._mediaController.stopRecording(userId, sourceId, recId);
return Promise.resolve(answer);
return (answer);
}
catch (err) {
Logger.error("[MCSApi] stopRecording ", err);
return Promise.reject(err);
catch (error) {
throw (this._handleError(error, 'stopRecording', { userId, sourceId, recId }));
}
}
async connect (source, sink, type) {
try {
await this._mediaController.connect(source, sink, type);
return Promise.resolve();
return ;
}
catch (err) {
Logger.error(err);
return Promise.reject(err);
catch (error) {
throw (this._handleError(error, 'connect', { source, sink, type }));
}
}
async disconnect (source, sink, type) {
try {
await this._mediaController.disconnect(source, sink, type);
return Promise.resolve();
return ;
}
catch (err) {
Logger.error(err);
return Promise.reject(err);
catch (error) {
throw (this._handleError(error, 'disconnect', { source, sink, type }));
}
}
@ -150,26 +139,32 @@ module.exports = class MCSApiStub extends EventEmitter {
this.emitter.emit(eventTag, event);
});
return Promise.resolve(eventTag);
return (eventTag);
}
catch (err) {
Logger.error("[MCSApi] onEvent ", err);
return Promise.reject();
catch (error) {
throw (this._handleError(error, 'onEvent', { eventName, mediaId }));
}
}
async addIceCandidate (mediaId, candidate) {
try {
await this._mediaController.addIceCandidate(mediaId, candidate);
return Promise.resolve();
return ;
}
catch (err) {
Logger.error("[MCSApi] addIceCandidate ", err);
Promise.reject();
catch (error) {
throw (this._handleError(error, 'addIceCandidate', { mediaId, candidate }));
}
}
setStrategy (strategy) {
// TODO
}
_handleError (error, operation, params) {
const { code, message, details } = error;
const response = { type: 'error', code, message, details, operation, params};
Logger.error("[mcs-api] Reject operation", response.operation, "with", { error: response });
return response;
}
}

View File

@ -6,7 +6,8 @@ const Logger = require('../../../utils/Logger');
// Model
const SfuUser = require('../model/SfuUser');
const Room = require('../model/Room.js');
const isError = require('../utils/util').isError;
const { handleError } = require('../utils/util');
const LOG_PREFIX = "[mcs-controller]";
/* PUBLIC ELEMENTS */
@ -366,34 +367,6 @@ module.exports = class MediaController {
}
_handleError (error) {
let { message, code, stack, data, details } = error;
if (code == null) {
({ code, message } = C.ERROR.MEDIA_GENERIC_ERROR);
}
else {
({ code, message } = error);
}
if (!isError(error)) {
error = new Error(message);
}
error.code = code;
error.message = message;
error.stack = stack
if (details) {
error.details = details;
}
else {
error.details = message;
}
Logger.trace("[mcs-controller ] Controller received an error", error.code, error.message);
Logger.trace(error.stack);
return error;
return handleError(LOG_PREFIX, error);
}
}

View File

@ -12,7 +12,8 @@ const Freeswitch = require('../adapters/freeswitch/freeswitch');
const config = require('config');
const kurentoUrl = config.get('kurentoUrl');
const Logger = require('../../../utils/Logger');
const isError = require('../utils/util').isError;
const { handleError } = require('../utils/util');
const LOG_PREFIX = "[mcs-media-session]";
module.exports = class MediaSession {
constructor (
@ -164,34 +165,7 @@ module.exports = class MediaSession {
}
_handleError (error) {
let { message, code, stack, data, details } = error;
if (code == null) {
({ code, message } = C.ERROR.MEDIA_GENERIC_ERROR);
}
else {
({ code, message } = error);
}
if (!isError(error)) {
error = new Error(message);
}
error.code = code;
error.message = message;
error.stack = stack
if (details) {
error.details = details;
}
else {
error.details = message;
}
Logger.trace("[mcs-media-session] SFU MediaSession received an error", error.code, error.message); Logger.trace(error.stack);
this._status = C.STATUS.STOPPED;
return error;
return handleError(LOG_PREFIX, error);
}
}

View File

@ -17,14 +17,10 @@ module.exports = class Room {
}
setUser (user) {
if (typeof this._users[user.id] == 'undefined' ||
!this._users[user.id]) {
this._users[user.id] = {};
}
this._users[user.id] = user;
}
destroyUser(userId) {
this._users[userId] = null;;
this._users[userId] = null;
}
}

View File

@ -8,8 +8,9 @@
const rid = require('readable-id');
const User = require('./User');
const C = require('../constants/Constants.js');
const isError = require('../utils/util').isError;
const Logger = require('../../../utils/Logger');
const { handleError } = require('../utils/util');
const LOG_PREFIX = "[mcs-user]";
module.exports = class User {
constructor(roomId, type, userAgentString = C.STRING.ANONYMOUS) {
@ -19,33 +20,6 @@ module.exports = class User {
}
_handleError (error) {
let { message, code, stack, data, details } = error;
if (code == null) {
({ code, message } = C.ERROR.MEDIA_GENERIC_ERROR);
}
else {
({ code, message } = error);
}
if (!isError(error)) {
error = new Error(message);
}
error.code = code;
error.message = message;
error.stack = stack
if (details) {
error.details = details;
}
else {
error.details = message;
}
Logger.trace("[User] SFU User received an error", error.code, error.message);
Logger.trace(error.stack);
return error;
return handleError(LOG_PREFIX, error);
}
}

View File

@ -5,7 +5,44 @@
*
*/
exports.isError = function (error) {
const C = require('../constants/Constants');
exports.isError = (error) => {
return error && error.stack && error.message && typeof error.stack === 'string'
&& typeof error.message === 'string';
}
exports.handleError = (logPrefix, error) => {
let { message, code, stack, data, details } = error;
if (code && code >= C.ERROR.MIN_CODE && code <= C.ERROR.MAX_CODE) {
return error;
}
if (code == null) {
({ code, message } = C.ERROR.MEDIA_GENERIC_ERROR);
}
else {
({ code, message } = error);
}
if (!isError(error)) {
error = new Error(message);
}
error.code = code;
error.message = message;
error.stack = stack
if (details) {
error.details = details;
}
else {
error.details = message;
}
Logger.debug(logPrefix, "Handling error", error.code, error.message);
Logger.trace(logPrefix, error.stack);
return error;
}

View File

@ -15,23 +15,3 @@ exports.hrTime = function () {
return t[0]*1000 + parseInt(t[1]/1000000);
}
/*
* isRecordedStream
*
* Returns the stream id if it's not a flash stream and is recorded
*/
exports.isRecordedStream = function (stream) {
const flashStream = /^([A-z0-9]+)-([A-z0-9]+)-([A-z0-9+])(-recorded)?$/;
const recordedStream = /^([_A-z0-9]+)-recorded$/;
if (!stream.match(flashStream)) {
let res = stream.match(recordedStream);
if (res) {
return res[1];
}
}
return null;
}

View File

@ -251,7 +251,7 @@ module.exports = class Video extends EventEmitter {
return resolve(sdpAnswer);
}
catch (err) {
Logger.error("[video] MCS returned error => " + err);
Logger.error("[video] MCS returned error => ", err);
return reject(err);
}
});