diff --git a/src/SDataService.js b/src/SDataService.js index 7f0ba68..d7b7cc0 100644 --- a/src/SDataService.js +++ b/src/SDataService.js @@ -52,7 +52,9 @@ ? value['#text'] : value; }, - nsRE = /^(.+?):(.*)$/; + nsRE = /^(.+?):(.*)$/, + applicationJsonRE = /application\/json/i, + applicationXmlRE = /application\/xml/i; Sage.SData.Client.SDataService = Sage.Evented.extend({ uri: null, @@ -244,10 +246,12 @@ options.success.call(options.scope || this, feed); }, failure: function(response, opt) { - this.fireEvent('requestexception', request, opt, response); + var error = this.processError(response); + + this.fireEvent('requestexception', request, opt, error, response); if (options.failure) - options.failure.call(options.scope || this, response, opt); + options.failure.call(options.scope || this, error, response, opt); }, aborted: function(response, opt) { this.fireEvent('requestaborted', request, opt, response); @@ -876,12 +880,58 @@ return {'feed': result}; }, + processError: function(response) { + if (!response.responseText) return null; + + var contentType = response.getResponseHeader && response.getResponseHeader('Content-Type'); + + // There *must* be a Content-Type in order to process errors. Since there is currently no way to detect if the error was raised + // by the SData layer, or by the web server itself, in order to process error content, the Content-Type must be used. + if (applicationJsonRE.test(contentType)) + { + return JSON.parse(response.responseText); + } + else if (applicationXmlRE.test(contentType)) + { + var xml = new XML.ObjTree(); + xml.attr_prefix = '@'; + + var doc = xml.parseXML(response.responseText); + if (doc.hasOwnProperty('sdata:diagnoses')) + { + var raw = S.isArray(doc['sdata:diagnoses']) ? doc['sdata:diagnoses'] : [doc['sdata:diagnoses']], + diagnoses = []; + + for (var i = 0; i < raw.length; i++) + { + diagnoses.push({ + 'severity': raw[i]['sdata:severity'], + 'sdataCode': raw[i]['sdata:severity'], + 'applicationCode': raw[i]['sdata:severity'], + 'message': raw[i]['sdata:severity'], + 'stackTrace': raw[i]['sdata:severity'], + 'payloadPath': raw[i]['sdata:severity'] + }); + } + + return diagnoses; + } + else + { + return null; + } + } + else + { + return null; + } + }, processFeed: function(response) { if (!response.responseText) return null; var contentType = response.getResponseHeader && response.getResponseHeader('Content-Type'); - if (/application\/json/i.test(contentType) || (!contentType && this.isJsonEnabled())) + if (applicationJsonRE.test(contentType) || (!contentType && this.isJsonEnabled())) { var doc = JSON.parse(response.responseText); diff --git a/tests/SDataServiceTests.js b/tests/SDataServiceTests.js index 08d1a3a..14dee02 100644 --- a/tests/SDataServiceTests.js +++ b/tests/SDataServiceTests.js @@ -78,4 +78,12 @@ describe('SDataService', function() { expect(options).toHaveProperty('headers.Accept', 'application/atom+xml;type=feed;view=other,*/*;view=other'); })(Sage.SData.Client.Ajax.request.mostRecentCall.args[0]); }); + + it('can process error diagnoses from XML', function() { + + }); + + it('can process error diagnoses from XML', function() { + + }); }); \ No newline at end of file diff --git a/tests/TestError.json b/tests/TestError.json new file mode 100644 index 0000000..41d1100 --- /dev/null +++ b/tests/TestError.json @@ -0,0 +1,10 @@ +[ + { + "severity": "Error", + "sdataCode": "ApplicationNotFound", + "applicationCode": "", + "message": "Unable to locate a handler to process the request 'slx/dynamic/-/accountss'", + "stackTrace": "", + "payloadPath": "" + } +] \ No newline at end of file diff --git a/tests/TestError.xml b/tests/TestError.xml new file mode 100644 index 0000000..8e15cbd --- /dev/null +++ b/tests/TestError.xml @@ -0,0 +1,35 @@ + + + + error + ApplicationDiagnosis + + could not resolve property: dddd of: Sage.SalesLogix.Entities.Account + NHibernate.QueryException: could not resolve property: dddd of: Sage.SalesLogix.Entities.Account + at NHibernate.Persister.Entity.AbstractPropertyMapping.ToType(String propertyName) + at NHibernate.Persister.Entity.AbstractEntityPersister.GetSubclassPropertyTableNumber(String propertyPath) + at NHibernate.Persister.Entity.BasicEntityPropertyMapping.ToColumns(String alias, String propertyName) + at NHibernate.Persister.Entity.AbstractEntityPersister.ToColumns(String alias, String propertyName) + at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumns(ICriteria subcriteria, String propertyName) + at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumnsUsingProjection(ICriteria subcriteria, String propertyName) + at NHibernate.Criterion.PropertyProjection.ToSqlString(ICriteria criteria, Int32 loc, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) + at NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingProjection(IProjection projection, ICriteriaQuery criteriaQuery, ICriteria criteria, IDictionary`2 enabledFilters) + at NHibernate.Criterion.SimpleExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) + at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary`2 enabledFilters) + at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) + at NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, String rootEntityName, IDictionary`2 enabledFilters) + at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) + at NHibernate.Impl.CriteriaImpl.List(IList results) + at NHibernate.Impl.CriteriaImpl.UniqueResult[T]() + at Sage.Platform.SData.RequestHandlerBase`3.GetEntities(SDataUri uri, Int64& totalResults, Int32& startIndex, Int32& itemsPerPage) + at Sage.Platform.SData.RequestHandlerBase`3.InternalGet() + at Invoke731b667614574bd79affc71c8d960371.Invoke(Object , IRequest ) + at Sage.Integration.Messaging.RequestTargetRegistration.RequestTargetInvoker.Invoke(IRequest request) + at Sage.Integration.Messaging.Request.Process(RequestTargetInvoker invoker) + at Sage.Integration.Adapter.AdapterController.RealAdapterController.Process(IRequest request) + at Sage.Integration.Adapter.AdapterController.RealAdapterController.ProcessWorker(IProtocolRequest protocolRequest) + at Sage.Integration.Adapter.AdapterController.Process(IProtocolRequest request) + at Sage.Integration.Messaging.MessagingService.Process(IProtocolRequest protocolRequest) + + + \ No newline at end of file diff --git a/tests/TestErrorMany.xml b/tests/TestErrorMany.xml new file mode 100644 index 0000000..5206676 --- /dev/null +++ b/tests/TestErrorMany.xml @@ -0,0 +1,67 @@ + + + + error + ApplicationDiagnosis + + could not resolve property: dddd of: Sage.SalesLogix.Entities.Account + NHibernate.QueryException: could not resolve property: dddd of: Sage.SalesLogix.Entities.Account + at NHibernate.Persister.Entity.AbstractPropertyMapping.ToType(String propertyName) + at NHibernate.Persister.Entity.AbstractEntityPersister.GetSubclassPropertyTableNumber(String propertyPath) + at NHibernate.Persister.Entity.BasicEntityPropertyMapping.ToColumns(String alias, String propertyName) + at NHibernate.Persister.Entity.AbstractEntityPersister.ToColumns(String alias, String propertyName) + at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumns(ICriteria subcriteria, String propertyName) + at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumnsUsingProjection(ICriteria subcriteria, String propertyName) + at NHibernate.Criterion.PropertyProjection.ToSqlString(ICriteria criteria, Int32 loc, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) + at NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingProjection(IProjection projection, ICriteriaQuery criteriaQuery, ICriteria criteria, IDictionary`2 enabledFilters) + at NHibernate.Criterion.SimpleExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) + at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary`2 enabledFilters) + at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) + at NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, String rootEntityName, IDictionary`2 enabledFilters) + at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) + at NHibernate.Impl.CriteriaImpl.List(IList results) + at NHibernate.Impl.CriteriaImpl.UniqueResult[T]() + at Sage.Platform.SData.RequestHandlerBase`3.GetEntities(SDataUri uri, Int64& totalResults, Int32& startIndex, Int32& itemsPerPage) + at Sage.Platform.SData.RequestHandlerBase`3.InternalGet() + at Invoke731b667614574bd79affc71c8d960371.Invoke(Object , IRequest ) + at Sage.Integration.Messaging.RequestTargetRegistration.RequestTargetInvoker.Invoke(IRequest request) + at Sage.Integration.Messaging.Request.Process(RequestTargetInvoker invoker) + at Sage.Integration.Adapter.AdapterController.RealAdapterController.Process(IRequest request) + at Sage.Integration.Adapter.AdapterController.RealAdapterController.ProcessWorker(IProtocolRequest protocolRequest) + at Sage.Integration.Adapter.AdapterController.Process(IProtocolRequest request) + at Sage.Integration.Messaging.MessagingService.Process(IProtocolRequest protocolRequest) + + + + error + ApplicationDiagnosis + + could not resolve property: dddd of: Sage.SalesLogix.Entities.Account + NHibernate.QueryException: could not resolve property: dddd of: Sage.SalesLogix.Entities.Account + at NHibernate.Persister.Entity.AbstractPropertyMapping.ToType(String propertyName) + at NHibernate.Persister.Entity.AbstractEntityPersister.GetSubclassPropertyTableNumber(String propertyPath) + at NHibernate.Persister.Entity.BasicEntityPropertyMapping.ToColumns(String alias, String propertyName) + at NHibernate.Persister.Entity.AbstractEntityPersister.ToColumns(String alias, String propertyName) + at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumns(ICriteria subcriteria, String propertyName) + at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetColumnsUsingProjection(ICriteria subcriteria, String propertyName) + at NHibernate.Criterion.PropertyProjection.ToSqlString(ICriteria criteria, Int32 loc, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) + at NHibernate.Criterion.CriterionUtil.GetColumnNamesUsingProjection(IProjection projection, ICriteriaQuery criteriaQuery, ICriteria criteria, IDictionary`2 enabledFilters) + at NHibernate.Criterion.SimpleExpression.ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery, IDictionary`2 enabledFilters) + at NHibernate.Loader.Criteria.CriteriaQueryTranslator.GetWhereCondition(IDictionary`2 enabledFilters) + at NHibernate.Loader.Criteria.CriteriaJoinWalker..ctor(IOuterJoinLoadable persister, CriteriaQueryTranslator translator, ISessionFactoryImplementor factory, ICriteria criteria, String rootEntityName, IDictionary`2 enabledFilters) + at NHibernate.Loader.Criteria.CriteriaLoader..ctor(IOuterJoinLoadable persister, ISessionFactoryImplementor factory, CriteriaImpl rootCriteria, String rootEntityName, IDictionary`2 enabledFilters) + at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) + at NHibernate.Impl.CriteriaImpl.List(IList results) + at NHibernate.Impl.CriteriaImpl.UniqueResult[T]() + at Sage.Platform.SData.RequestHandlerBase`3.GetEntities(SDataUri uri, Int64& totalResults, Int32& startIndex, Int32& itemsPerPage) + at Sage.Platform.SData.RequestHandlerBase`3.InternalGet() + at Invoke731b667614574bd79affc71c8d960371.Invoke(Object , IRequest ) + at Sage.Integration.Messaging.RequestTargetRegistration.RequestTargetInvoker.Invoke(IRequest request) + at Sage.Integration.Messaging.Request.Process(RequestTargetInvoker invoker) + at Sage.Integration.Adapter.AdapterController.RealAdapterController.Process(IRequest request) + at Sage.Integration.Adapter.AdapterController.RealAdapterController.ProcessWorker(IProtocolRequest protocolRequest) + at Sage.Integration.Adapter.AdapterController.Process(IProtocolRequest request) + at Sage.Integration.Messaging.MessagingService.Process(IProtocolRequest protocolRequest) + + + \ No newline at end of file