Ohif 168 proper error handling (#111)
* Adding a better error handling for DICOMWeb getJson method * Adding a better error handling for DICOMWeb getBulkData method * Fixinf some typos. Using console.error to log errors * Better error handling for DIMSE connections * Using meteor error in StudyListSearch to better display same error in the client * Using Meteor.Error for a better pattern. Added an error message in the study list. created connection error types to DICOMWeb connection errors * Changing error types for server connection. Added better errors for DIMSE server on sockets * Improving viewer response to error being throw when not finding server to display studies * OHIF-168: adding catches clauses for retrieveStudyMetada method * OHIF-168: fixing typo in DIMSE.js * OHIF-168: setting the session variable to false when starting a new studylist search * OHIF-168: Using OHIF.log instead of console * OHIF-168: removing parsing into string for OHIF.log in Connection.js * OHIF-168: improving error message visibility in study viewer
This commit is contained in:
parent
4c5dcfeab0
commit
af4b8b45f5
@ -1,3 +1,5 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
const ASCII = 'ascii';
|
const ASCII = 'ascii';
|
||||||
const http = Npm.require('http')
|
const http = Npm.require('http')
|
||||||
const url = Npm.require('url');
|
const url = Npm.require('url');
|
||||||
@ -165,6 +167,14 @@ function makeRequest(geturl, options, callback) {
|
|||||||
data.push(chunk);
|
data.push(chunk);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
resp.on('error', function (responseError) {
|
||||||
|
OHIF.log.error('There was an error in the DICOMWeb Server');
|
||||||
|
OHIF.log.error(responseError.stack);
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
callback(responseError, null);
|
||||||
|
});
|
||||||
|
|
||||||
resp.on('end', function() {
|
resp.on('end', function() {
|
||||||
try {
|
try {
|
||||||
callback(null, parseResponse(resp.headers, Buffer.concat(data)));
|
callback(null, parseResponse(resp.headers, Buffer.concat(data)));
|
||||||
@ -175,6 +185,15 @@ function makeRequest(geturl, options, callback) {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
req.on('error', function (requestError) {
|
||||||
|
OHIF.log.error('Couldn\'t connect to DICOMWeb server.');
|
||||||
|
OHIF.log.error('Make sure you are trying to connect to the right server and that it is up and running.');
|
||||||
|
OHIF.log.error(requestError.stack);
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
callback(requestError, null);
|
||||||
|
});
|
||||||
|
|
||||||
req.end();
|
req.end();
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -185,7 +204,7 @@ const makeRequestSync = Meteor.wrapAsync(makeRequest);
|
|||||||
DICOMWeb.getBulkData = function(geturl, options) {
|
DICOMWeb.getBulkData = function(geturl, options) {
|
||||||
|
|
||||||
if (options.logRequests) {
|
if (options.logRequests) {
|
||||||
console.log(geturl);
|
OHIF.log.info(geturl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.logTiming) {
|
if (options.logTiming) {
|
||||||
@ -199,7 +218,7 @@ DICOMWeb.getBulkData = function(geturl, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.logResponses) {
|
if (options.logResponses) {
|
||||||
console.log(result);
|
OHIF.log.info(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Buffer.isBuffer(result)) {
|
if (!Buffer.isBuffer(result)) {
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { Meteor } from 'meteor/meteor';
|
import { Meteor } from 'meteor/meteor';
|
||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
const http = Npm.require('http');
|
const http = Npm.require('http');
|
||||||
const https = Npm.require('https');
|
const https = Npm.require('https');
|
||||||
@ -52,14 +53,35 @@ function makeRequest(geturl, options, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let output = '';
|
let output = '';
|
||||||
|
|
||||||
resp.setEncoding('utf8');
|
resp.setEncoding('utf8');
|
||||||
resp.on('data', function(chunk) {
|
|
||||||
output += chunk;
|
resp.on('data', function(chunk){
|
||||||
|
output += chunk;
|
||||||
});
|
});
|
||||||
resp.on('end', function() {
|
|
||||||
callback(null, { data: JSON.parse(output) });
|
resp.on('error', function (responseError) {
|
||||||
|
OHIF.log.error('There was an error in the DICOMWeb Server')
|
||||||
|
OHIF.log.error(error.stack);
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
callback(new Meteor.Error('server-internal-error', responseError.message), null);
|
||||||
|
});
|
||||||
|
|
||||||
|
resp.on('end', function(){
|
||||||
|
callback(null, { data: JSON.parse(output) });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
req.on('error', function (requestError) {
|
||||||
|
OHIF.log.error('Couldn\'t connect to DICOMWeb server.');
|
||||||
|
OHIF.log.error('Make sure you are trying to connect to the right server and that it is up and running.');
|
||||||
|
OHIF.log.error(requestError.stack);
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
callback(new Meteor.Error('server-connection-error', requestError.message), null);
|
||||||
|
});
|
||||||
|
|
||||||
req.end();
|
req.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,7 +89,7 @@ const makeRequestSync = Meteor.wrapAsync(makeRequest);
|
|||||||
|
|
||||||
DICOMWeb.getJSON = function(geturl, options) {
|
DICOMWeb.getJSON = function(geturl, options) {
|
||||||
if (options.logRequests) {
|
if (options.logRequests) {
|
||||||
console.log(geturl);
|
OHIF.log.info(geturl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.logTiming) {
|
if (options.logTiming) {
|
||||||
@ -81,7 +103,7 @@ DICOMWeb.getJSON = function(geturl, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.logResponses) {
|
if (options.logResponses) {
|
||||||
console.log(result);
|
OHIF.log.info(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
var EventEmitter = Npm.require('events').EventEmitter;
|
var EventEmitter = Npm.require('events').EventEmitter;
|
||||||
|
|
||||||
function time() {
|
function time() {
|
||||||
@ -41,37 +43,49 @@ CSocket = function(socket, options) {
|
|||||||
|
|
||||||
var o = this;
|
var o = this;
|
||||||
this.socket.on('connect', function() {
|
this.socket.on('connect', function() {
|
||||||
console.log('Connect');
|
OHIF.log.info('Connect');
|
||||||
o.ready();
|
o.ready();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.socket.on('data', function(data) {
|
this.socket.on('data', function(data) {
|
||||||
o.received(data);
|
o.received(data);
|
||||||
});
|
});
|
||||||
this.socket.on('error', function(he) {
|
|
||||||
console.log('Error: ', he);
|
this.socket.on('error', function(socketError) {
|
||||||
throw 'Error: ' + he;
|
OHIF.log.error('There was an error with DIMSE connection socket.');
|
||||||
|
OHIF.log.error(socketError.stack);
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
o.emit('error', new Meteor.Error('server-internal-error', socketError.message));
|
||||||
});
|
});
|
||||||
this.socket.on('timeout', function(he) {
|
|
||||||
console.log('Timeout: ', he);
|
this.socket.on('timeout', function(socketError) {
|
||||||
throw 'Timeout: ' + he;
|
OHIF.log.error('The connection timed out. The server is not responding.');
|
||||||
|
OHIF.log.error(socketError.stack);
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
o.emit('error', new Meteor.Error('server-connection-error', socketError.message));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.socket.on('close', function() {
|
this.socket.on('close', function() {
|
||||||
if (o.intervalId) {
|
if (o.intervalId) {
|
||||||
clearInterval(o.intervalId);
|
clearInterval(o.intervalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
o.connected = false;
|
o.connected = false;
|
||||||
console.log('Connection closed');
|
OHIF.log.info('Connection closed');
|
||||||
o.emit('close');
|
o.emit('close');
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('released', function() {
|
this.on('released', function() {
|
||||||
this.released();
|
this.released();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('aborted', function(pdu) {
|
this.on('aborted', function(pdu) {
|
||||||
console.warn('Association aborted with reason ' + pdu.reason);
|
OHIF.log.warn('Association aborted with reason ' + pdu.reason);
|
||||||
this.released();
|
this.released();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on('message', function(pdvs) {
|
this.on('message', function(pdvs) {
|
||||||
this.receivedMessage(pdvs);
|
this.receivedMessage(pdvs);
|
||||||
});
|
});
|
||||||
@ -213,7 +227,7 @@ CSocket.prototype.released = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
CSocket.prototype.ready = function() {
|
CSocket.prototype.ready = function() {
|
||||||
console.log('Connection established');
|
OHIF.log.info('Connection established');
|
||||||
this.connected = true;
|
this.connected = true;
|
||||||
this.started = time();
|
this.started = time();
|
||||||
|
|
||||||
@ -237,7 +251,7 @@ CSocket.prototype.checkIdle = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
CSocket.prototype.idleClose = function() {
|
CSocket.prototype.idleClose = function() {
|
||||||
console.log('Exceed idle time, closing connection');
|
OHIF.log.info('Exceed idle time, closing connection');
|
||||||
this.release();
|
this.release();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -283,7 +297,7 @@ CSocket.prototype.process = function(data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log('Data received');
|
OHIF.log.info('Data received');
|
||||||
var newData = Buffer.concat([this.receiving, data], this.receiving.length + data.length),
|
var newData = Buffer.concat([this.receiving, data], this.receiving.length + data.length),
|
||||||
pduLength = newData.length - 6;
|
pduLength = newData.length - 6;
|
||||||
|
|
||||||
@ -398,7 +412,7 @@ CSocket.prototype.receivedMessage = function(pdv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (msg.failure()) {
|
if (msg.failure()) {
|
||||||
console.log('message failed with status ', msg.getStatus().toString(16));
|
OHIF.log.info('message failed with status ', msg.getStatus().toString(16));
|
||||||
}
|
}
|
||||||
|
|
||||||
listener.emit('response', msg);
|
listener.emit('response', msg);
|
||||||
@ -452,7 +466,10 @@ CSocket.prototype.receivedMessage = function(pdv) {
|
|||||||
} else {
|
} else {
|
||||||
throw 'Where does this c-store came from?';
|
throw 'Where does this c-store came from?';
|
||||||
}
|
}
|
||||||
} else console.log('move ', moveMessageId);
|
} else{
|
||||||
|
OHIF.log.info('move ', moveMessageId);
|
||||||
|
}
|
||||||
|
|
||||||
//this.storeResponse(useId, msg);
|
//this.storeResponse(useId, msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -508,7 +525,7 @@ CSocket.prototype.sendMessage = function(context, command, dataset) {
|
|||||||
|
|
||||||
msgData.command = command;
|
msgData.command = command;
|
||||||
this.messages[messageId] = msgData;
|
this.messages[messageId] = msgData;
|
||||||
console.log('Sending command ' + command.typeString());
|
OHIF.log.info('Sending command ' + command.typeString());
|
||||||
this.send(pdata);
|
this.send(pdata);
|
||||||
if (dataset && typeof dataset === 'object') {
|
if (dataset && typeof dataset === 'object') {
|
||||||
dataset.setSyntax(syntax);
|
dataset.setSyntax(syntax);
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { _ } from 'meteor/underscore';
|
import { _ } from 'meteor/underscore';
|
||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
// Uses NodeJS 'net'
|
// Uses NodeJS 'net'
|
||||||
// https://nodejs.org/api/net.html
|
// https://nodejs.org/api/net.html
|
||||||
@ -62,10 +63,10 @@ Connection.prototype.addPeer = function(options) {
|
|||||||
//start listening
|
//start listening
|
||||||
peer.server = net.createServer();
|
peer.server = net.createServer();
|
||||||
peer.server.listen(options.port, options.host, function() {
|
peer.server.listen(options.port, options.host, function() {
|
||||||
console.log('listening on %j', this.address());
|
OHIF.log.info('listening on', this.address());
|
||||||
});
|
});
|
||||||
peer.server.on('error', function(err) {
|
peer.server.on('error', function(err) {
|
||||||
console.log('server error %j', err);
|
OHIF.log.info('server error', err);
|
||||||
});
|
});
|
||||||
peer.server.on('connection', nativeSocket => {
|
peer.server.on('connection', nativeSocket => {
|
||||||
//incoming connections
|
//incoming connections
|
||||||
@ -90,13 +91,13 @@ Connection.prototype.selectPeer = function(aeTitle) {
|
|||||||
|
|
||||||
Connection.prototype._sendFile = function(socket, sHandle, file, maxSend, metaLength, list) {
|
Connection.prototype._sendFile = function(socket, sHandle, file, maxSend, metaLength, list) {
|
||||||
var fileNameText = typeof file.file === 'string' ? file.file : 'buffer';
|
var fileNameText = typeof file.file === 'string' ? file.file : 'buffer';
|
||||||
console.log('Sending file ' + fileNameText);
|
OHIF.log.info(`Sending file ${fileNameText}`);
|
||||||
var useContext = socket.getContextByUID(file.context);
|
var useContext = socket.getContextByUID(file.context);
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
PDU.generatePDatas(useContext.id, file.file, maxSend, null, metaLength, function(err, handle) {
|
PDU.generatePDatas(useContext.id, file.file, maxSend, null, metaLength, function(err, handle) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.log('Error while sending file');
|
OHIF.log.info('Error while sending file');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +120,7 @@ Connection.prototype._sendFile = function(socket, sHandle, file, maxSend, metaLe
|
|||||||
});
|
});
|
||||||
store.on('response', function(msg) {
|
store.on('response', function(msg) {
|
||||||
var statusText = msg.getStatus().toString(16);
|
var statusText = msg.getStatus().toString(16);
|
||||||
console.log('STORE reponse with status', statusText);
|
OHIF.log.info('STORE reponse with status', statusText);
|
||||||
var error = null;
|
var error = null;
|
||||||
if (msg.failure()) {
|
if (msg.failure()) {
|
||||||
error = new Error(statusText);
|
error = new Error(statusText);
|
||||||
@ -153,7 +154,7 @@ Connection.prototype.storeInstances = function(fileList) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Dicom file ' + (typeof bufferOrFile === 'string' ? bufferOrFile : 'buffer') + ' found');
|
OHIF.log.info(`Dicom file ${(typeof bufferOrFile === 'string' ? bufferOrFile : 'buffer')} found`);
|
||||||
lastProcessedMetaLength = metaLength;
|
lastProcessedMetaLength = metaLength;
|
||||||
var syntax = metaMessage.getValue(0x00020010);
|
var syntax = metaMessage.getValue(0x00020010);
|
||||||
var sopClassUID = metaMessage.getValue(0x00020002);
|
var sopClassUID = metaMessage.getValue(0x00020002);
|
||||||
@ -248,6 +249,7 @@ Connection.prototype.addSocket = function(hostAE, socket) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Connection.prototype.associate = function(options, callback) {
|
Connection.prototype.associate = function(options, callback) {
|
||||||
|
const self = this;
|
||||||
var hostAE = options.hostAE ? options.hostAE : this.defaultPeer;
|
var hostAE = options.hostAE ? options.hostAE : this.defaultPeer;
|
||||||
var sourceAE = options.sourceAE ? options.sourceAE : this.defaultServer;
|
var sourceAE = options.sourceAE ? options.sourceAE : this.defaultServer;
|
||||||
|
|
||||||
@ -264,7 +266,7 @@ Connection.prototype.associate = function(options, callback) {
|
|||||||
socket.once('associated', callback);
|
socket.once('associated', callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Starting Connection...');
|
OHIF.log.info('Starting Connection...');
|
||||||
|
|
||||||
socket.setCalledAe(hostAE);
|
socket.setCalledAe(hostAE);
|
||||||
socket.setCallingAE(sourceAE);
|
socket.setCallingAE(sourceAE);
|
||||||
@ -279,7 +281,7 @@ Connection.prototype.associate = function(options, callback) {
|
|||||||
if (options.contexts) {
|
if (options.contexts) {
|
||||||
socket.setPresentationContexts(options.contexts);
|
socket.setPresentationContexts(options.contexts);
|
||||||
} else {
|
} else {
|
||||||
throw 'Contexts must be specified';
|
throw new Meteor.Error('Contexts must be specified');
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.associate();
|
socket.associate();
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
var Future = Npm.require('fibers/future');
|
var Future = Npm.require('fibers/future');
|
||||||
|
|
||||||
DIMSE = {
|
DIMSE = {
|
||||||
@ -75,23 +77,34 @@ DIMSE.associate = function(contexts, callback, options) {
|
|||||||
};
|
};
|
||||||
options = Object.assign(defaults, options);
|
options = Object.assign(defaults, options);
|
||||||
|
|
||||||
console.log('Associating...');
|
OHIF.log.info('Associating...');
|
||||||
try {
|
|
||||||
conn.associate(options, function(pdu) {
|
const socket = conn.associate(options, function(pdu) {
|
||||||
// associated
|
// associated
|
||||||
console.log('==Associated');
|
OHIF.log.info('==Associated');
|
||||||
callback.call(this, pdu);
|
callback(null, pdu);
|
||||||
});
|
});
|
||||||
} catch(error) {
|
|
||||||
console.error('dimse-associate: ' + error);
|
socket.on('error', function (error) {
|
||||||
throw new Meteor.Error('dimse-associate', error);
|
callback(error, null);
|
||||||
}
|
});
|
||||||
|
|
||||||
|
socket.on('timeout', function (error) {
|
||||||
|
callback(error, null);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
DIMSE.retrievePatients = function(params, options) {
|
DIMSE.retrievePatients = function(params, options) {
|
||||||
//var start = new Date();
|
//var start = new Date();
|
||||||
var future = new Future;
|
var future = new Future;
|
||||||
DIMSE.associate([C.SOP_PATIENT_ROOT_FIND], function(pdu) {
|
DIMSE.associate([C.SOP_PATIENT_ROOT_FIND], function(error, pdu) {
|
||||||
|
if (error) {
|
||||||
|
OHIF.log.error('Could not retrieve patients');
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
return future.return([]);
|
||||||
|
}
|
||||||
|
|
||||||
var defaultParams = {
|
var defaultParams = {
|
||||||
0x00100010: '',
|
0x00100010: '',
|
||||||
0x00100020: '',
|
0x00100020: '',
|
||||||
@ -124,7 +137,14 @@ DIMSE.retrievePatients = function(params, options) {
|
|||||||
DIMSE.retrieveStudies = function(params, options) {
|
DIMSE.retrieveStudies = function(params, options) {
|
||||||
//var start = new Date();
|
//var start = new Date();
|
||||||
var future = new Future;
|
var future = new Future;
|
||||||
DIMSE.associate([C.SOP_STUDY_ROOT_FIND], function(pdu) {
|
DIMSE.associate([C.SOP_STUDY_ROOT_FIND], function(error, pdu) {
|
||||||
|
if (error) {
|
||||||
|
OHIF.log.error('Could not retrieve studies');
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
return future.throw(error);
|
||||||
|
}
|
||||||
|
|
||||||
var defaultParams = {
|
var defaultParams = {
|
||||||
0x0020000D: '',
|
0x0020000D: '',
|
||||||
0x00080060: '',
|
0x00080060: '',
|
||||||
@ -201,7 +221,14 @@ DIMSE.retrieveInstancesByStudyOnly = function(studyInstanceUID, params, options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
var future = new Future;
|
var future = new Future;
|
||||||
DIMSE.associate([C.SOP_STUDY_ROOT_FIND], function(pdu) {
|
DIMSE.associate([C.SOP_STUDY_ROOT_FIND], function(error, pdu) {
|
||||||
|
if (error) {
|
||||||
|
OHIF.log.error('Could not retrieve Instances By Study');
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
return future.throw(error);
|
||||||
|
}
|
||||||
|
|
||||||
var defaultParams = {
|
var defaultParams = {
|
||||||
0x0020000D: studyInstanceUID,
|
0x0020000D: studyInstanceUID,
|
||||||
0x00080005: '',
|
0x00080005: '',
|
||||||
@ -244,7 +271,14 @@ DIMSE.retrieveInstancesByStudyOnly = function(studyInstanceUID, params, options)
|
|||||||
|
|
||||||
DIMSE.retrieveSeries = function(studyInstanceUID, params, options) {
|
DIMSE.retrieveSeries = function(studyInstanceUID, params, options) {
|
||||||
var future = new Future;
|
var future = new Future;
|
||||||
DIMSE.associate([C.SOP_STUDY_ROOT_FIND], function(pdu) {
|
DIMSE.associate([C.SOP_STUDY_ROOT_FIND], function(error, pdu) {
|
||||||
|
if (error) {
|
||||||
|
OHIF.log.error('Could not retrieve series');
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
return future.return([]);
|
||||||
|
}
|
||||||
|
|
||||||
var defaultParams = {
|
var defaultParams = {
|
||||||
0x0020000D: studyInstanceUID ? studyInstanceUID : '',
|
0x0020000D: studyInstanceUID ? studyInstanceUID : '',
|
||||||
0x00080005: '',
|
0x00080005: '',
|
||||||
@ -280,7 +314,14 @@ DIMSE.retrieveSeries = function(studyInstanceUID, params, options) {
|
|||||||
|
|
||||||
DIMSE.retrieveInstances = function(studyInstanceUID, seriesInstanceUID, params, options) {
|
DIMSE.retrieveInstances = function(studyInstanceUID, seriesInstanceUID, params, options) {
|
||||||
var future = new Future;
|
var future = new Future;
|
||||||
DIMSE.associate([C.SOP_STUDY_ROOT_FIND], function(pdu) {
|
DIMSE.associate([C.SOP_STUDY_ROOT_FIND], function(error, pdu) {
|
||||||
|
if (error) {
|
||||||
|
OHIF.log.error('Could not retrieve instances');
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
return future.throw(error);
|
||||||
|
}
|
||||||
|
|
||||||
var defaultParams = getInstanceRetrievalParams(studyInstanceUID, seriesInstanceUID);
|
var defaultParams = getInstanceRetrievalParams(studyInstanceUID, seriesInstanceUID);
|
||||||
var result = this.findInstances(Object.assign(defaultParams, params)),
|
var result = this.findInstances(Object.assign(defaultParams, params)),
|
||||||
o = this;
|
o = this;
|
||||||
@ -309,7 +350,14 @@ DIMSE.storeInstances = function(fileList, callback) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DIMSE.moveInstances = function(studyInstanceUID, seriesInstanceUID, sopInstanceUID, sopClassUID, params) {
|
DIMSE.moveInstances = function(studyInstanceUID, seriesInstanceUID, sopInstanceUID, sopClassUID, params) {
|
||||||
DIMSE.associate([C.SOP_STUDY_ROOT_MOVE, sopClassUID], function() {
|
DIMSE.associate([C.SOP_STUDY_ROOT_MOVE, sopClassUID], function(error) {
|
||||||
|
if (error) {
|
||||||
|
OHIF.log.error('Could not move instances');
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var defaultParams = {
|
var defaultParams = {
|
||||||
0x0020000D: studyInstanceUID ? studyInstanceUID : '',
|
0x0020000D: studyInstanceUID ? studyInstanceUID : '',
|
||||||
0x0020000E: seriesInstanceUID ? seriesInstanceUID : '',
|
0x0020000E: seriesInstanceUID ? seriesInstanceUID : '',
|
||||||
|
|||||||
@ -59,6 +59,11 @@ function renderIntoViewport(viewportIndex, studyInstanceUid, seriesInstanceUid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
findAndRenderDisplaySet(study.displaySets, viewportIndex, studyInstanceUid, seriesInstanceUid, sopInstanceUid, renderedCallback);
|
findAndRenderDisplaySet(study.displaySets, viewportIndex, studyInstanceUid, seriesInstanceUid, sopInstanceUid, renderedCallback);
|
||||||
|
}).catch(error => {
|
||||||
|
OHIF.log.error(`There was an error trying to retrieve the study\'s metadata for studyInstanceUid: ${studyInstanceUid}`);
|
||||||
|
OHIF.log.error(error.stack);
|
||||||
|
|
||||||
|
OHIF.log.trace();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,9 +80,13 @@
|
|||||||
{{#if session "showLoadingText"}}
|
{{#if session "showLoadingText"}}
|
||||||
{{>loadingText}}
|
{{>loadingText}}
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#unless numberOfStudies}}
|
{{#if session "serverError"}}
|
||||||
<div class="notFound">No matching results</div>
|
<div class="notFound">There was an error fetching studies</div>
|
||||||
{{/unless}}
|
{{else}}
|
||||||
|
{{#unless numberOfStudies}}
|
||||||
|
<div class="notFound">No matching results</div>
|
||||||
|
{{/unless}}
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import { moment } from 'meteor/momentjs:moment';
|
|||||||
import { OHIF } from 'meteor/ohif:core';
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
Session.setDefault('showLoadingText', true);
|
Session.setDefault('showLoadingText', true);
|
||||||
|
Session.setDefault('serverError', false);
|
||||||
|
|
||||||
Template.studylistResult.helpers({
|
Template.studylistResult.helpers({
|
||||||
/**
|
/**
|
||||||
@ -132,6 +133,9 @@ function search() {
|
|||||||
// Show loading message
|
// Show loading message
|
||||||
Session.set('showLoadingText', true);
|
Session.set('showLoadingText', true);
|
||||||
|
|
||||||
|
// Hiding error message
|
||||||
|
Session.set('serverError', false);
|
||||||
|
|
||||||
// Create the filters to be used for the StudyList Search
|
// Create the filters to be used for the StudyList Search
|
||||||
filter = {
|
filter = {
|
||||||
patientName: getFilter($('input#patientName').val()),
|
patientName: getFilter($('input#patientName').val()),
|
||||||
@ -152,14 +156,27 @@ function search() {
|
|||||||
|
|
||||||
Meteor.call('StudyListSearch', filter, (error, studies) => {
|
Meteor.call('StudyListSearch', filter, (error, studies) => {
|
||||||
OHIF.log.info('StudyListSearch');
|
OHIF.log.info('StudyListSearch');
|
||||||
|
// Hide loading text
|
||||||
|
|
||||||
|
Session.set('showLoadingText', false);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
OHIF.log.warn(error);
|
Session.set('serverError', true);
|
||||||
|
|
||||||
|
const errorType = error.error;
|
||||||
|
|
||||||
|
if (errorType === 'server-connection-error') {
|
||||||
|
OHIF.log.error('There was an error connecting to the DICOM server, please verify if it is up and running.');
|
||||||
|
} else if (errorType === 'server-internal-error') {
|
||||||
|
OHIF.log.error('There was an internal error with the DICOM server');
|
||||||
|
} else {
|
||||||
|
OHIF.log.error('For some reason we could not list the studies.')
|
||||||
|
}
|
||||||
|
|
||||||
|
OHIF.log.error(error.stack);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide loading text
|
|
||||||
Session.set('showLoadingText', false);
|
|
||||||
|
|
||||||
if (!studies) {
|
if (!studies) {
|
||||||
OHIF.log.warn('No studies found');
|
OHIF.log.warn('No studies found');
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -53,7 +53,7 @@ export class OHIFStudyMetadataSource extends OHIF.viewerbase.StudyMetadataSource
|
|||||||
|
|
||||||
OHIFStudyMetadataSource._updateStudyCollections(studyMetadata);
|
OHIFStudyMetadataSource._updateStudyCollections(studyMetadata);
|
||||||
resolve(studyMetadata);
|
resolve(studyMetadata);
|
||||||
}, reject);
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -43,6 +43,11 @@ queryStudiesWithProgress = function(studiesToQuery) {
|
|||||||
dialog.done(studiesQueried);
|
dialog.done(studiesQueried);
|
||||||
}, () => {
|
}, () => {
|
||||||
dialog.cancel();
|
dialog.cancel();
|
||||||
|
}).catch(error => {
|
||||||
|
OHIF.log.error('There was an error retrieving all studies metadeta.');
|
||||||
|
OHIF.log.error(error.stack);
|
||||||
|
|
||||||
|
OHIF.log.trace();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,8 +34,20 @@ OHIF.studylist.retrieveStudyMetadata = (studyInstanceUid, seriesInstanceUids) =>
|
|||||||
console.timeEnd('retrieveStudyMetadata');
|
console.timeEnd('retrieveStudyMetadata');
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
OHIF.log.error(error);
|
const errorType = error.error;
|
||||||
reject(error);
|
let errorMessage = '';
|
||||||
|
|
||||||
|
if (errorType === 'server-connection-error') {
|
||||||
|
errorMessage = 'There was an error connecting to the DICOM server, please verify if it is up and running.'
|
||||||
|
} else if (errorType === 'server-internal-error') {
|
||||||
|
errorMessage = `There was an internal error with the DICOM server getting metadeta for ${studyInstanceUid}`;
|
||||||
|
} else {
|
||||||
|
errorMessage = `For some reason we could not retrieve the study\'s metadata for ${studyInstanceUid}.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
OHIF.log.error(errorMessage);
|
||||||
|
OHIF.log.error(error.stack);
|
||||||
|
reject(`GetStudyMetadata: ${errorMessage}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -14,13 +14,19 @@ Meteor.methods({
|
|||||||
const server = OHIF.servers.getCurrentServer();
|
const server = OHIF.servers.getCurrentServer();
|
||||||
|
|
||||||
if (!server) {
|
if (!server) {
|
||||||
throw 'No properly configured server was available over DICOMWeb or DIMSE.';
|
throw new Meteor.Error('improper-server-config', 'No properly configured server was available over DICOMWeb or DIMSE.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server.type === 'dicomWeb') {
|
try {
|
||||||
return Services.WADO.RetrieveMetadata(server, studyInstanceUid);
|
if (server.type === 'dicomWeb') {
|
||||||
} else if (server.type === 'dimse') {
|
return Services.WADO.RetrieveMetadata(server, studyInstanceUid);
|
||||||
return Services.DIMSE.RetrieveMetadata(studyInstanceUid);
|
} else if (server.type === 'dimse') {
|
||||||
|
return Services.DIMSE.RetrieveMetadata(studyInstanceUid);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,13 +13,19 @@ Meteor.methods({
|
|||||||
const server = OHIF.servers.getCurrentServer();
|
const server = OHIF.servers.getCurrentServer();
|
||||||
|
|
||||||
if (!server) {
|
if (!server) {
|
||||||
throw 'No properly configured server was available over DICOMWeb or DIMSE.';
|
throw new Meteor.Error('improper-server-config', 'No properly configured server was available over DICOMWeb or DIMSE.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server.type === 'dicomWeb') {
|
try {
|
||||||
return Services.QIDO.Studies(server, filter);
|
if (server.type === 'dicomWeb') {
|
||||||
} else if (server.type === 'dimse') {
|
return Services.QIDO.Studies(server, filter);
|
||||||
return Services.DIMSE.Studies(filter);
|
} else if (server.type === 'dimse') {
|
||||||
|
return Services.DIMSE.Studies(filter);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a QIDO URL given the server settings and a study instance UID
|
* Creates a QIDO URL given the server settings and a study instance UID
|
||||||
* @param server
|
* @param server
|
||||||
@ -69,15 +71,24 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
|
|||||||
* Retrieve a set of instances using a QIDO call
|
* Retrieve a set of instances using a QIDO call
|
||||||
* @param server
|
* @param server
|
||||||
* @param studyInstanceUid
|
* @param studyInstanceUid
|
||||||
|
* @throws ECONNREFUSED
|
||||||
* @returns {{wadoUriRoot: String, studyInstanceUid: String, seriesList: Array}}
|
* @returns {{wadoUriRoot: String, studyInstanceUid: String, seriesList: Array}}
|
||||||
*/
|
*/
|
||||||
Services.QIDO.Instances = function(server, studyInstanceUid) {
|
Services.QIDO.Instances = function(server, studyInstanceUid) {
|
||||||
var url = buildUrl(server, studyInstanceUid);
|
var url = buildUrl(server, studyInstanceUid);
|
||||||
var result = DICOMWeb.getJSON(url, server.requestOptions);
|
|
||||||
|
|
||||||
return {
|
try {
|
||||||
wadoUriRoot: server.wadoUriRoot,
|
var result = DICOMWeb.getJSON(url, server.requestOptions);
|
||||||
studyInstanceUid: studyInstanceUid,
|
|
||||||
seriesList: resultDataToStudyMetadata(server, studyInstanceUid, result.data)
|
return {
|
||||||
};
|
wadoUriRoot: server.wadoUriRoot,
|
||||||
|
studyInstanceUid: studyInstanceUid,
|
||||||
|
seriesList: resultDataToStudyMetadata(server, studyInstanceUid, result.data)
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a QIDO date string for a date range query
|
* Creates a QIDO date string for a date range query
|
||||||
* Assumes the year is positive, at most 4 digits long.
|
* Assumes the year is positive, at most 4 digits long.
|
||||||
@ -91,6 +93,14 @@ function resultDataToStudies(resultData) {
|
|||||||
|
|
||||||
Services.QIDO.Studies = function(server, filter) {
|
Services.QIDO.Studies = function(server, filter) {
|
||||||
var url = filterToQIDOURL(server, filter);
|
var url = filterToQIDOURL(server, filter);
|
||||||
var result = DICOMWeb.getJSON(url, server.requestOptions);
|
|
||||||
return resultDataToStudies(result.data);
|
try {
|
||||||
|
var result = DICOMWeb.getJSON(url, server.requestOptions);
|
||||||
|
|
||||||
|
return resultDataToStudies(result.data);
|
||||||
|
} catch (error) {
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { OHIF } from 'meteor/ohif:core';
|
||||||
import { parseFloatArray } from '../../lib/parseFloatArray';
|
import { parseFloatArray } from '../../lib/parseFloatArray';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -148,7 +149,7 @@ function getPaletteColors(server, instance, lutDescriptor) {
|
|||||||
paletteColorCache.add(entry);
|
paletteColorCache.add(entry);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`(${error.name}) ${error.message}`);
|
OHIF.log.error(`(${error.name}) ${error.message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,15 +340,21 @@ function resultDataToStudyMetadata(server, studyInstanceUid, resultData) {
|
|||||||
Services.WADO.RetrieveMetadata = function(server, studyInstanceUid) {
|
Services.WADO.RetrieveMetadata = function(server, studyInstanceUid) {
|
||||||
var url = buildUrl(server, studyInstanceUid);
|
var url = buildUrl(server, studyInstanceUid);
|
||||||
|
|
||||||
var result = DICOMWeb.getJSON(url, server.requestOptions);
|
try {
|
||||||
|
var result = DICOMWeb.getJSON(url, server.requestOptions);
|
||||||
|
|
||||||
var study = resultDataToStudyMetadata(server, studyInstanceUid, result.data);
|
var study = resultDataToStudyMetadata(server, studyInstanceUid, result.data);
|
||||||
if (!study) {
|
if (!study) {
|
||||||
study = {};
|
study = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
study.wadoUriRoot = server.wadoUriRoot;
|
||||||
|
study.studyInstanceUid = studyInstanceUid;
|
||||||
|
|
||||||
|
return study;
|
||||||
|
} catch (error) {
|
||||||
|
OHIF.log.trace();
|
||||||
|
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
study.wadoUriRoot = server.wadoUriRoot;
|
|
||||||
study.studyInstanceUid = studyInstanceUid;
|
|
||||||
|
|
||||||
return study;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,3 +2,4 @@
|
|||||||
font-weight: 300
|
font-weight: 300
|
||||||
padding: 30px
|
padding: 30px
|
||||||
text-align: center
|
text-align: center
|
||||||
|
color: #ffffff
|
||||||
|
|||||||
@ -117,6 +117,11 @@ Template.studyTimepointStudy.events({
|
|||||||
$studies.trigger('loadEnded');
|
$studies.trigger('loadEnded');
|
||||||
instance.select(isQuickSwitch);
|
instance.select(isQuickSwitch);
|
||||||
}, 1);
|
}, 1);
|
||||||
|
}).catch(error => {
|
||||||
|
OHIF.log.error(`There was an error trying to retrieve the study\'s metadata for studyInstanceUid: ${studyInstanceUid}`);
|
||||||
|
OHIF.log.error(error.stack);
|
||||||
|
|
||||||
|
OHIF.log.trace();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
studyData.seriesList = alreadyLoaded.seriesList;
|
studyData.seriesList = alreadyLoaded.seriesList;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user