rets-client
Advanced tools
Comparing version 4.1.4 to 4.2.0
@@ -38,2 +38,4 @@ // Generated by CoffeeScript 1.10.0 | ||
RetsServerError: errors.RetsServerError, | ||
RetsProcessingError: errors.RetsProcessingError, | ||
RetsParamError: errors.RetsParamError, | ||
Client: Client, | ||
@@ -40,0 +42,0 @@ getAutoLogoutClient: Client.getAutoLogoutClient, |
@@ -10,3 +10,3 @@ // Generated by CoffeeScript 1.10.0 | ||
'use strict'; | ||
var Promise, _getMetadataImpl, getMetadata, getSystem, replyCodes, retsHttp, retsParsing, through2, | ||
var Promise, _getMetadataImpl, errors, getMetadata, getSystem, replyCodes, retsHttp, retsParsing, through2, | ||
hasProp = {}.hasOwnProperty; | ||
@@ -24,6 +24,8 @@ | ||
errors = require('../utils/errors'); | ||
_getMetadataImpl = function(retsSession, type, options) { | ||
return new Promise(function(resolve, reject) { | ||
var context, currEntry, result; | ||
context = retsParsing.getStreamParser(type); | ||
context = retsParsing.getStreamParser('getMetadata', type); | ||
retsHttp.streamRetsMethod('getMetadata', retsSession, options, context.fail, context.response).pipe(context.parser); | ||
@@ -96,6 +98,6 @@ result = { | ||
if (!type) { | ||
throw new Error('Metadata type is required'); | ||
throw new errors.RetsParamError('Metadata type is required'); | ||
} | ||
if (!id) { | ||
throw new Error('Resource type id is required (or for some types of metadata, "0" retrieves for all resource types)'); | ||
throw new errors.RetsParamError('Resource type id is required (or for some types of metadata, "0" retrieves for all resource types)'); | ||
} | ||
@@ -122,3 +124,3 @@ options = { | ||
result = {}; | ||
retsParser = retsParsing.getSimpleParser(reject, xmlResponse.headerInfo); | ||
retsParser = retsParsing.getSimpleParser('getMetadata', reject, xmlResponse.headerInfo); | ||
gotMetaDataInfo = false; | ||
@@ -144,3 +146,3 @@ gotSystemInfo = false; | ||
if (!gotSystemInfo || !gotMetaDataInfo) { | ||
return reject(new Error('Failed to parse data')); | ||
return reject(new errors.RetsProcessingError('getMetadata', 'Failed to parse data')); | ||
} else { | ||
@@ -159,3 +161,3 @@ return resolve(result); | ||
if (!_retsSession) { | ||
throw new Error('System data not set; invoke login().'); | ||
throw new errors.RetsParamError('System data not set; invoke login().'); | ||
} | ||
@@ -170,3 +172,3 @@ _getParsedMetadataFactory = function(type, format) { | ||
if (!id) { | ||
throw new Error('Resource type id is required (or for some types of metadata, "0" retrieves for all resource types)'); | ||
throw new errors.RetsParamError('Resource type id is required (or for some types of metadata, "0" retrieves for all resource types)'); | ||
} | ||
@@ -173,0 +175,0 @@ options = { |
@@ -10,3 +10,3 @@ // Generated by CoffeeScript 1.10.0 | ||
'use strict'; | ||
var Promise, WritableStreamBuffer, _loadStreams, getAllObjects, getObjects, getPreferredObjects, multipart, queryOptionHelpers, retsHttp, through2; | ||
var Promise, WritableStreamBuffer, _loadStreams, errors, getAllObjects, getObjects, getPreferredObjects, multipart, queryOptionHelpers, retsHttp, through2; | ||
@@ -25,2 +25,4 @@ WritableStreamBuffer = require('stream-buffers').WritableStreamBuffer; | ||
errors = require('../utils/errors'); | ||
_loadStreams = function(result) { | ||
@@ -167,3 +169,3 @@ return new Promise(function(resolve, reject) { | ||
if (!_retsSession) { | ||
throw new Error('System data not set; invoke login().'); | ||
throw new errors.RetsParamError('System data not set; invoke login().'); | ||
} | ||
@@ -170,0 +172,0 @@ return { |
@@ -10,3 +10,3 @@ // Generated by CoffeeScript 1.10.0 | ||
'use strict'; | ||
var Promise, _annotateIds, _insensitiveStartsWith, _processBody, base64, getAllObjects, getObjects, getPreferredObjects, headersHelper, multipart, queryOptionHelpers, retsHttp, retsParsing, through2; | ||
var Promise, _annotateIds, _insensitiveStartsWith, _processBody, base64, errors, getAllObjects, getObjects, getPreferredObjects, headersHelper, multipart, queryOptionHelpers, retsHttp, retsParsing, through2; | ||
@@ -29,2 +29,4 @@ Promise = require('bluebird'); | ||
errors = require('../utils/errors'); | ||
_insensitiveStartsWith = function(str, prefix) { | ||
@@ -38,10 +40,7 @@ return str.toLowerCase().lastIndexOf(prefix.toLowerCase(), 0) === 0; | ||
headerInfo = headersHelper.processHeaders(headers); | ||
onError = function(error) { | ||
return reject(errors.ensureRetsError('getObject', error, headerInfo)); | ||
}; | ||
if (_insensitiveStartsWith(headerInfo.contentType, 'text/xml')) { | ||
onError = function(error) { | ||
return reject({ | ||
headerInfo: headerInfo, | ||
error: error | ||
}); | ||
}; | ||
retsParser = retsParsing.getSimpleParser(onError, headerInfo); | ||
retsParser = retsParsing.getSimpleParser('getObject', onError, headerInfo); | ||
return bodyStream.pipe(retsParser.parser); | ||
@@ -55,6 +54,3 @@ } else if (_insensitiveStartsWith(headerInfo.contentType, 'multipart')) { | ||
})["catch"](function(error) { | ||
return reject({ | ||
headerInfo: headerInfo, | ||
error: error | ||
}); | ||
return onError(error); | ||
}); | ||
@@ -70,3 +66,3 @@ } else { | ||
bodyStream.on('error', function(err) { | ||
return b64.emit('error', err); | ||
return b64.emit('error', errors.ensureRetsError('getObject', err, headerInfo)); | ||
}); | ||
@@ -80,3 +76,3 @@ return resolve({ | ||
headerInfo: headerInfo, | ||
error: new Error("unknown transfer encoding: " + (JSON.stringify(headerInfo.transferEncoding))) | ||
error: new errors.RetsProcessingError('getObject', "unknown transfer encoding: " + (JSON.stringify(headerInfo.transferEncoding)), headerInfo) | ||
}); | ||
@@ -158,9 +154,9 @@ } | ||
if (!resourceType) { | ||
throw new Error('Resource type id is required'); | ||
throw new errors.RetsParamError('Resource type id is required'); | ||
} | ||
if (!objectType) { | ||
throw new Error('Object type id is required'); | ||
throw new errors.RetsParamError('Object type id is required'); | ||
} | ||
if (!ids) { | ||
throw new Error('Ids are required'); | ||
throw new errors.RetsParamError('Ids are required'); | ||
} | ||
@@ -208,3 +204,3 @@ idString = ''; | ||
done = true; | ||
return reject(error); | ||
return reject(errors.ensureRetsError('getObject', error)); | ||
}; | ||
@@ -218,3 +214,7 @@ req = retsHttp.streamRetsMethod('getObject', _this.retsSession, options, fail); | ||
done = true; | ||
return resolve(_processBody(response.rawHeaders, bodyStream, true)); | ||
return _processBody(response.rawHeaders, bodyStream, true).then(function(result) { | ||
return resolve(result); | ||
})["catch"](function(error) { | ||
return fail(error); | ||
}); | ||
}); | ||
@@ -261,3 +261,3 @@ return bodyStream = req.pipe(through2()); | ||
if (!_retsSession) { | ||
throw new Error('System data not set; invoke login().'); | ||
throw new errors.RetsParamError('System data not set; invoke login().'); | ||
} | ||
@@ -264,0 +264,0 @@ return { |
@@ -29,3 +29,5 @@ // Generated by CoffeeScript 1.10.0 | ||
errors = require('../utils/errors'); | ||
/* | ||
@@ -131,3 +133,3 @@ * Invokes RETS search operation. | ||
if (!_retsSession) { | ||
throw new Error('System data not set; invoke login().'); | ||
throw new errors.RetsParamError('System data not set; invoke login().'); | ||
} | ||
@@ -134,0 +136,0 @@ return { |
@@ -10,3 +10,3 @@ // Generated by CoffeeScript 1.10.0 | ||
'use strict'; | ||
var query, queryOptionHelpers, retsHttp, retsParsing, searchRets, through2; | ||
var errors, query, queryOptionHelpers, retsHttp, retsParsing, searchRets, through2; | ||
@@ -21,3 +21,5 @@ through2 = require('through2'); | ||
errors = require('../utils/errors'); | ||
/* | ||
@@ -101,3 +103,3 @@ * Invokes RETS search operation and streams the resulting XML. | ||
finalQueryOptions = queryOptionHelpers.normalizeOptions(queryOptions); | ||
context = retsParsing.getStreamParser(null, rawData); | ||
context = retsParsing.getStreamParser('search', null, rawData); | ||
retsHttp.streamRetsMethod('search', this.retsSession, finalQueryOptions, context.fail, context.response).pipe(context.parser); | ||
@@ -109,3 +111,3 @@ return context.retsStream; | ||
if (!_retsSession) { | ||
throw new Error('System data not set; invoke login().'); | ||
throw new errors.RetsParamError('System data not set; invoke login().'); | ||
} | ||
@@ -112,0 +114,0 @@ return { |
@@ -10,3 +10,3 @@ // Generated by CoffeeScript 1.10.0 | ||
'use strict'; | ||
var Promise, headersHelper, login, logout, retsHttp, retsParsing; | ||
var Promise, errors, headersHelper, login, logout, retsHttp, retsParsing; | ||
@@ -21,3 +21,5 @@ Promise = require('bluebird'); | ||
errors = require('./errors'); | ||
/* | ||
@@ -36,3 +38,3 @@ * Executes RETS login routine. | ||
}; | ||
retsParser = retsParsing.getSimpleParser(reject, headers); | ||
retsParser = retsParsing.getSimpleParser('login', reject, headers); | ||
gotData = false; | ||
@@ -64,3 +66,3 @@ retsParser.parser.on('text', function(text) { | ||
if (!gotData) { | ||
return reject(new Error('Failed to parse data')); | ||
return reject(new errors.RetsProcessingError('login', 'Failed to parse data', headers)); | ||
} else { | ||
@@ -67,0 +69,0 @@ return resolve(systemData); |
@@ -10,3 +10,3 @@ // Generated by CoffeeScript 1.10.0 | ||
'use strict'; | ||
var RetsError, RetsReplyError, RetsServerError, headersHelper, replyCodes, | ||
var RetsError, RetsParamError, RetsProcessingError, RetsReplyError, RetsServerError, ensureRetsError, getErrorMessage, headersHelper, replyCodes, util, | ||
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, | ||
@@ -19,2 +19,22 @@ hasProp = {}.hasOwnProperty; | ||
util = require('util'); | ||
getErrorMessage = function(err) { | ||
var inspect; | ||
if (err == null) { | ||
return JSON.stringify(err); | ||
} | ||
if (err.message) { | ||
return err.message; | ||
} | ||
if (err.toString() === '[object Object]') { | ||
inspect = util.inspect(err, { | ||
depth: null | ||
}); | ||
return inspect.replace(/,?\n +\w+: undefined/g, ''); | ||
} else { | ||
return err.toString(); | ||
} | ||
}; | ||
RetsError = (function(superClass) { | ||
@@ -34,3 +54,4 @@ extend(RetsError, superClass); | ||
function RetsReplyError(replyCode, replyText, _headerInfo) { | ||
function RetsReplyError(retsMethod1, replyCode, replyText, _headerInfo) { | ||
this.retsMethod = retsMethod1; | ||
this.replyCode = replyCode; | ||
@@ -40,3 +61,3 @@ this.replyText = replyText; | ||
this.replyTag = replyCodes.tagMap[this.replyCode] != null ? replyCodes.tagMap[this.replyCode] : 'unknown reply code'; | ||
this.message = "RETS Server replied with an error code - ReplyCode " + this.replyCode + " (" + this.replyTag + "); ReplyText: " + this.replyText; | ||
this.message = "RETS Server reply while attempting " + this.retsMethod + " - ReplyCode " + this.replyCode + " (" + this.replyTag + "); ReplyText: " + this.replyText; | ||
this.headerInfo = headersHelper.processHeaders(_headerInfo); | ||
@@ -53,8 +74,8 @@ Error.captureStackTrace(this, RetsReplyError); | ||
function RetsServerError(retsMethod, httpStatus, httpStatusMessage, _headerInfo) { | ||
this.retsMethod = retsMethod; | ||
function RetsServerError(retsMethod1, httpStatus, httpStatusMessage, _headerInfo) { | ||
this.retsMethod = retsMethod1; | ||
this.httpStatus = httpStatus; | ||
this.httpStatusMessage = httpStatusMessage; | ||
this.name = 'RetsServerError'; | ||
this.message = "Error while attempting " + this.retsMethod + " - HTTP Status " + this.httpStatus + " returned (" + this.httpStatusMessage + ")"; | ||
this.message = "RETS Server error while attempting " + this.retsMethod + " - HTTP Status " + this.httpStatus + " returned (" + this.httpStatusMessage + ")"; | ||
this.headerInfo = headersHelper.processHeaders(_headerInfo); | ||
@@ -68,8 +89,49 @@ Error.captureStackTrace(this, RetsServerError); | ||
RetsProcessingError = (function(superClass) { | ||
extend(RetsProcessingError, superClass); | ||
function RetsProcessingError(retsMethod1, sourceError, _headerInfo) { | ||
this.retsMethod = retsMethod1; | ||
this.sourceError = sourceError; | ||
this.name = 'RetsProcessingError'; | ||
this.message = "Error while processing RETS response for " + this.retsMethod + " - " + (getErrorMessage(this.sourceError)); | ||
this.headerInfo = headersHelper.processHeaders(_headerInfo); | ||
Error.captureStackTrace(this, RetsProcessingError); | ||
} | ||
return RetsProcessingError; | ||
})(RetsError); | ||
RetsParamError = (function(superClass) { | ||
extend(RetsParamError, superClass); | ||
function RetsParamError(message) { | ||
this.message = message; | ||
this.name = 'RetsParamError'; | ||
Error.captureStackTrace(this, RetsParamError); | ||
} | ||
return RetsParamError; | ||
})(RetsError); | ||
ensureRetsError = function(retsMethod, error, headerInfo) { | ||
if (error instanceof RetsError) { | ||
return error; | ||
} else { | ||
return new RetsProcessingError(retsMethod, error, headerInfo); | ||
} | ||
}; | ||
module.exports = { | ||
RetsError: RetsError, | ||
RetsReplyError: RetsReplyError, | ||
RetsServerError: RetsServerError | ||
RetsServerError: RetsServerError, | ||
RetsProcessingError: RetsProcessingError, | ||
RetsParamError: RetsParamError, | ||
ensureRetsError: ensureRetsError, | ||
getErrorMessage: getErrorMessage | ||
}; | ||
}).call(this); |
@@ -10,3 +10,3 @@ // Generated by CoffeeScript 1.10.0 | ||
'use strict'; | ||
var MultipartParser, Promise, getObjectStream, retsParsing, through2; | ||
var MultipartParser, Promise, errors, getObjectStream, retsParsing, through2; | ||
@@ -21,2 +21,4 @@ MultipartParser = require('formidable/lib/multipart_parser').MultipartParser; | ||
errors = require('./errors'); | ||
getObjectStream = function(headerInfo, stream, handler) { | ||
@@ -30,3 +32,3 @@ return new Promise(function(resolve, reject) { | ||
if (!multipartBoundary) { | ||
throw new Error('Could not find multipart boundary'); | ||
throw new errors.RetsProcessingError('getObject', 'Could not find multipart boundary', headerInfo); | ||
} | ||
@@ -104,3 +106,5 @@ parser = new MultipartParser(); | ||
} | ||
})["catch"](handleError).then(function() { | ||
})["catch"](function(err) { | ||
return handleError(errors.ensureRetsError('getObject', err, headers)); | ||
}).then(function() { | ||
partDone = true; | ||
@@ -139,3 +143,3 @@ return handleEnd(); | ||
if (err) { | ||
handleError(new Error("Unexpected end of data: " + err)); | ||
handleError(new errors.RetsProcessingError('getObject', "Unexpected end of data: " + (errors.getErrorMessage(err)), headerInfo)); | ||
} | ||
@@ -142,0 +146,0 @@ flushed = true; |
@@ -10,6 +10,8 @@ // Generated by CoffeeScript 1.10.0 | ||
'use strict'; | ||
var _queryOptionsDefaults, mergeOptions, normalizeOptions, | ||
var _queryOptionsDefaults, errors, mergeOptions, normalizeOptions, | ||
slice = [].slice, | ||
hasProp = {}.hasOwnProperty; | ||
errors = require('./errors'); | ||
mergeOptions = function() { | ||
@@ -43,12 +45,12 @@ var args, i, index, key, options, ref, result; | ||
if (!queryOptions) { | ||
throw new Error('queryOptions is required.'); | ||
throw errors.RetsParamError('search', 'queryOptions is required.'); | ||
} | ||
if (!queryOptions.searchType) { | ||
throw new Error('searchType is required (ex: Property'); | ||
throw errors.RetsProcessingError('search', 'searchType is required (ex: Property'); | ||
} | ||
if (!queryOptions["class"]) { | ||
throw new Error('class is required (ex: RESI)'); | ||
throw errors.RetsProcessingError('search', 'class is required (ex: RESI)'); | ||
} | ||
if (!queryOptions.query) { | ||
throw new Error('query is required (ex: (MatrixModifiedDT=2014-01-01T00:00:00.000+) )'); | ||
throw errors.RetsProcessingError('search', 'query is required (ex: (MatrixModifiedDT=2014-01-01T00:00:00.000+) )'); | ||
} | ||
@@ -55,0 +57,0 @@ return mergeOptions(queryOptions, _queryOptionsDefaults); |
@@ -65,3 +65,3 @@ // Generated by CoffeeScript 1.10.0 | ||
if (response.statusCode !== 200) { | ||
error = new errors.RetsServerError('search', response.statusCode, response.statusMessage, response.rawHeaders); | ||
error = new errors.RetsServerError(methodName, response.statusCode, response.statusMessage, response.rawHeaders); | ||
debug("RETS " + methodName + " error: " + error.message); | ||
@@ -68,0 +68,0 @@ return failCallback(error); |
@@ -24,3 +24,3 @@ // Generated by CoffeeScript 1.10.0 | ||
getSimpleParser = function(errCallback, headerInfo) { | ||
getSimpleParser = function(retsMethod, errCallback, headerInfo) { | ||
var result; | ||
@@ -38,3 +38,3 @@ result = { | ||
result.finish(); | ||
return errCallback(new Error('Unexpected results. Please check the RETS URL.')); | ||
return errCallback(new errors.RetsProcessingError(retsMethod, 'Unexpected results. Please check the RETS URL.', headerInfo)); | ||
} | ||
@@ -50,3 +50,3 @@ }); | ||
result.finish(); | ||
return errCallback(new errors.RetsReplyError(attrs.ReplyCode, attrs.ReplyText, headerInfo)); | ||
return errCallback(new errors.RetsReplyError(retsMethod, attrs.ReplyCode, attrs.ReplyText, headerInfo)); | ||
} | ||
@@ -56,7 +56,7 @@ }); | ||
result.finish(); | ||
return errCallback(new Error("XML parsing error: " + err)); | ||
return errCallback(new errors.RetsProcessingError(retsMethod, "XML parsing error: " + (errors.getErrorMessage(err)), headerInfo)); | ||
}); | ||
result.parser.on('end', function() { | ||
result.finish(); | ||
return errCallback(new Error("Unexpected end of xml stream.")); | ||
return errCallback(new errors.RetsProcessingError(retsMethod, "Unexpected end of xml stream.", headerInfo)); | ||
}); | ||
@@ -66,3 +66,3 @@ return result; | ||
getStreamParser = function(metadataTag, rawData) { | ||
getStreamParser = function(retsMethod, metadataTag, rawData) { | ||
var columnText, columns, currElementName, dataText, delimiter, fail, finish, headers, parser, processStatus, response, result, retsStream, writeOutput; | ||
@@ -118,3 +118,3 @@ if (metadataTag) { | ||
if (attrs.ReplyCode !== '0' && attrs.ReplyCode !== '20208') { | ||
return fail(new errors.RetsReplyError(attrs.ReplyCode, attrs.ReplyText, headers)); | ||
return fail(new errors.RetsReplyError(retsMethod, attrs.ReplyCode, attrs.ReplyText, headers)); | ||
} | ||
@@ -130,3 +130,3 @@ status = { | ||
if (name !== 'RETS') { | ||
return fail(new Error('Unexpected results. Please check the RETS URL.')); | ||
return fail(new errors.RetsProcessingError(retsMethod, 'Unexpected results. Please check the RETS URL.', headers)); | ||
} | ||
@@ -184,3 +184,3 @@ processStatus(attrs); | ||
if (!columns) { | ||
return fail(new Error('Failed to parse columns')); | ||
return fail(new errors.RetsProcessingError(retsMethod, 'Failed to parse columns', headers)); | ||
} | ||
@@ -198,3 +198,3 @@ data = dataText.split(delimiter); | ||
if (!delimiter) { | ||
return fail(new Error('Failed to parse delimiter')); | ||
return fail(new errors.RetsProcessingError(retsMethod, 'Failed to parse delimiter', headers)); | ||
} | ||
@@ -215,6 +215,6 @@ columns = columnText.split(delimiter); | ||
parser.on('error', function(err) { | ||
return fail(new Error("XML parsing error: " + err.stack)); | ||
return fail(new errors.RetsProcessingError(retsMethod, "XML parsing error: " + (errors.getErrorMessage(err)), headers)); | ||
}); | ||
parser.on('end', function() { | ||
return fail(new Error("Unexpected end of xml stream.")); | ||
return fail(new errors.RetsProcessingError(retsMethod, "Unexpected end of xml stream.", headers)); | ||
}); | ||
@@ -221,0 +221,0 @@ return { |
{ | ||
"name": "rets-client", | ||
"version": "4.1.4", | ||
"version": "4.2.0", | ||
"description": "A RETS client (Real Estate Transaction Standard).", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -162,3 +162,3 @@ rets-client | ||
//perform a query using DQML2 -- pass resource, class, and query, and options | ||
//perform a query using DMQL2 -- pass resource, class, and query, and options | ||
return client.search.query("OpenHouse", "OPENHOUSE", "(OpenHouseType=PUBLIC),(ActiveYN=1)", {limit:100, offset:10}) | ||
@@ -300,6 +300,11 @@ .then(function (searchData) { | ||
##### Errors | ||
There are 3 error classes exposed by this module: | ||
There are 5 error classes exposed by this module: | ||
* `RetsParamError`: Used when a required function parameter is missing or has an invalid value | ||
* `RetsServerError`: Used when the HTTP response indicates an error, such as a "401 Unauthorized" response | ||
* `RetsReplyError`: Used when the HTTP response is valid, but the XML RETS response indicates an error | ||
* `RetsError`: A parent class for the two above, to make it more convenient to catch errors of either type | ||
* `RetsProcessingError`: Used when a problem is encountered processing the response from the RETS server | ||
* `RetsError`: A parent class for all the errors above, to make it more convenient to catch errors from this library. | ||
I've made somewhat of an effort to catch any errors thrown by dependencies of this library and re-throw them as instances | ||
of RetsError, so that any error generated by a call to this library can be detected the same way; if you find an error | ||
coming through that didn't get this treatment, please open a ticket (or better, a PR!) to let me know. | ||
@@ -318,2 +323,2 @@ ##### Debugging | ||
dev dependencies (in particular, request-debug) are installed for rets-client. The easiest way to do this is to first | ||
change directory to the location of rets-client (e.g. `cd ./node_modules/rets-client`), and then run `npm install`. | ||
change directory to the location of rets-client (e.g. `cd ./node_modules/rets-client`), and then run `npm install`. |
88023
1852
322