From 78aba671b2cb3b9232554994c5f57ca6b2c246d0 Mon Sep 17 00:00:00 2001 From: Claudia Murialdo Date: Fri, 20 May 2022 17:26:10 -0300 Subject: [PATCH 1/2] Handle exception using ErrorHandler when iterating through a result set. --- .../GxClasses/Data/GXDataADO.cs | 55 ++++++++++--------- .../GxClasses/Data/GXDataNTier.cs | 13 +---- .../GxClasses/Data/GXDataNTierADO.cs | 37 +++++++++---- 3 files changed, 58 insertions(+), 47 deletions(-) diff --git a/dotnet/src/dotnetframework/GxClasses/Data/GXDataADO.cs b/dotnet/src/dotnetframework/GxClasses/Data/GXDataADO.cs index 9545b3719..bf2d2a540 100644 --- a/dotnet/src/dotnetframework/GxClasses/Data/GXDataADO.cs +++ b/dotnet/src/dotnetframework/GxClasses/Data/GXDataADO.cs @@ -1650,19 +1650,37 @@ public string ExecuteDataSet() } catch(GxADODataException e) { - bool pe = dataRecord.ProcessError( e.DBMSErrorCode, e.ErrorInfo, errMask, con, ref status, ref retry, retryCount); + bool pe = ProcessException(e, ref retry, retryCount, "EXECUTE"); retryCount++; - processErrorHandler( status, e.DBMSErrorCode, e.SqlState, e.ErrorInfo, errMask, "EXECUTE", ref pe, ref retry); if (! pe) { GXLogging.Error(log, e, "GxCommand.ExecuteDataSet Error "); - throw (new GxADODataException(e.ToString(), e)); + throw; } } } return ""; } + internal bool ProcessException(GxADODataException e, ref bool retry, int retryCount, string method) + { + bool pe = dataRecord.ProcessError(e.DBMSErrorCode, e.ErrorInfo, errMask, con, ref status, ref retry, retryCount); + processErrorHandler(status, e.DBMSErrorCode, e.SqlState, e.ErrorInfo, errMask, method, ref pe, ref retry); + if (!pe) + { + try + { + Close(); + con.Close(); + } + catch (Exception ex) + { + GXLogging.Warn(log, ex, "GxCommand.Close Error on ProcessException"); + } + } + return pe; + } + public IDataReader ExecuteReader() { try @@ -1730,22 +1748,12 @@ public void FetchData(out IDataReader dr) catch (GxADODataException e) { status=0; - bool pe = dataRecord.ProcessError( e.DBMSErrorCode, e.ErrorInfo, errMask, con, ref status, ref retry, retryCount); + bool pe = ProcessException(e, ref retry, retryCount, "FETCH"); retryCount++; - processErrorHandler( status, e.DBMSErrorCode, e.SqlState, e.ErrorInfo, errMask, "FETCH", ref pe, ref retry); if (! pe) { GXLogging.Error(log, e, "GxCommand.FetchData Error "); - try - { - Close(); - con.Close(); - } - catch(Exception ex) - { - GXLogging.Error(log, ex, "GxCommand.FetchData-Close Error "); - } - throw (new GxADODataException(e.ToString(), e)); + throw; } } } @@ -1767,13 +1775,12 @@ public void FetchDataRPC(out IDataReader dr) catch (GxADODataException e) { status=0; - bool pe = dataRecord.ProcessError( e.DBMSErrorCode, e.ErrorInfo, errMask, con, ref status, ref retry, retryCount); + bool pe = ProcessException(e, ref retry, retryCount, "FETCH"); retryCount++; - processErrorHandler( status, e.DBMSErrorCode, e.SqlState, e.ErrorInfo, errMask, "FETCH", ref pe, ref retry); if (! pe) { GXLogging.Error(log, e, "GxCommand.FetchDataRPC Error "); - throw (new GxADODataException(e.ToString(), e)); + throw; } } } @@ -1890,13 +1897,12 @@ public void ExecuteBatch() } catch (GxADODataException e) { - bool pe = dataRecord.ProcessError(e.DBMSErrorCode, e.ErrorInfo, errMask, con, ref status, ref retry, retryCount); + bool pe = ProcessException(e, ref retry, retryCount, "EXECUTE"); retryCount++; - processErrorHandler(status, e.DBMSErrorCode, e.SqlState, e.ErrorInfo, errMask, "EXECUTE", ref pe, ref retry); if (!pe) { GXLogging.Error(log, "GxCommand.ExecuteStmt Error ", e); - throw (new GxADODataException(e.ToString(), e)); + throw; } } } @@ -1919,14 +1925,13 @@ private void execStmt() status = 0; } catch (GxADODataException e) - { - bool pe = dataRecord.ProcessError(e.DBMSErrorCode, e.ErrorInfo, errMask, con, ref status, ref retry, retryCount); + { + bool pe = ProcessException(e, ref retry, retryCount, "EXECUTE"); retryCount++; - processErrorHandler(status, e.DBMSErrorCode, e.SqlState, e.ErrorInfo, errMask, "EXECUTE", ref pe, ref retry); if (!pe) { GXLogging.Error(log, "GxCommand.ExecuteStmt Error ", e); - throw (new GxADODataException(e.ToString(), e)); + throw; } } } diff --git a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTier.cs b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTier.cs index d843042b5..63bb25d39 100644 --- a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTier.cs +++ b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTier.cs @@ -489,7 +489,6 @@ public void readNext(int cursor) oCur.readNext(); _dataStoreHelper.getResults(cursor, oCur.getFieldGetter(), results[cursor]); dataStoreRequestCount++; - } public int getStatus(int cursorIdx) { @@ -538,19 +537,15 @@ private void commitDataStore(IGxDataStore ds, String auditObjectName) catch (Exception dbEx) { //If commit fails it should not retry, it makes no sense because it will no longer be possible. just close the existing connection. - int status = 0; GxADODataException e = new GxADODataException(dbEx); bool retry = false; int retryCount = 0; - bool pe = ds.Connection.DataRecord.ProcessError(e.DBMSErrorCode, e.ErrorInfo, cmd.ErrorMask, ds.Connection, ref status, ref retry, retryCount); GXLogging.Error(log, "Commit Transaction Error", e); - retryCount++; - cmd.processErrorHandler(status, e.DBMSErrorCode, e.SqlState, e.ErrorInfo, cmd.ErrorMask, "FETCH", ref pe, ref retry); + bool pe = cmd.ProcessException(e, ref retry, retryCount, "FETCH"); if (!pe) { try { - ds.Connection.Close(); if (retry) ds.Connection.Open(); } @@ -574,19 +569,15 @@ private void rollbackDataStore(IGxDataStore ds, String auditObjectName) } catch (Exception dbEx) { - int status = 0; GxADODataException e = new GxADODataException(dbEx); bool retry = false; int retryCount = 0; - bool pe = ds.Connection.DataRecord.ProcessError(e.DBMSErrorCode, e.ErrorInfo, cmd.ErrorMask, ds.Connection, ref status, ref retry, retryCount); + bool pe = cmd.ProcessException(e, ref retry, retryCount, "FETCH"); GXLogging.Error(log, "Rollback Transaction Error", e); - retryCount++; - cmd.processErrorHandler(status, e.DBMSErrorCode, e.SqlState, e.ErrorInfo, cmd.ErrorMask, "FETCH", ref pe, ref retry); if (!pe) { try { - ds.Connection.Close(); if (retry) ds.Connection.Open(); } diff --git a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs index 661e348b5..95163c45a 100644 --- a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs +++ b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs @@ -1198,18 +1198,33 @@ public override void readNext() throw (new GxADODataException("Could not readNext in ForEachCursor:" + _name + ".")); _status = 0; - if (!_DR.Read()) - { - _status = Cursor.EOF; - _gxDbCommand.HasMoreRows = false; - } - else if (_gxDbCommand.Status == 1 || _gxDbCommand.Status == 103 || _gxDbCommand.Status == 500) - { - _status = _gxDbCommand.Status; - } + try + { + if (!_DR.Read()) + { + _status = Cursor.EOF; + _gxDbCommand.HasMoreRows = false; + } + else if (_gxDbCommand.Status == 1 || _gxDbCommand.Status == 103 || _gxDbCommand.Status == 500) + { + _status = _gxDbCommand.Status; + } + } + catch (GxADODataException e) + { + bool retry = false; + int retryCount = 0; + bool pe = _gxDbCommand.ProcessException(e, ref retry, retryCount, "FETCH"); + GXLogging.Error(log, "readNext Error", e); + if (!pe) + { + throw; + } + } - } - } + + } + } public class UpdateCursor : Cursor { public UpdateCursor(CursorDef def) : base(def.Name, def.Stmt, def.Nmask, def.ParmBinds, 0) From 2d50ccb46391b0f43c7bf7dfb91def95d759ab9d Mon Sep 17 00:00:00 2001 From: Claudia Murialdo Date: Fri, 20 May 2022 17:59:45 -0300 Subject: [PATCH 2/2] Move error handling of readNext to a higher level in order to capture errors on _dataStoreHelper.getResults. --- .../GxClasses/Data/GXDataNTier.cs | 23 +++++++++-- .../GxClasses/Data/GXDataNTierADO.cs | 41 +++++++------------ 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTier.cs b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTier.cs index 63bb25d39..fdde9883e 100644 --- a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTier.cs +++ b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTier.cs @@ -485,10 +485,25 @@ private void execute(int cursor, Object[] parms, bool batch) public void readNext(int cursor) { - ICursor oCur = getCursor(cursor); - oCur.readNext(); - _dataStoreHelper.getResults(cursor, oCur.getFieldGetter(), results[cursor]); - dataStoreRequestCount++; + Cursor oCur = getCursor(cursor) as Cursor; + try + { + oCur.readNext(); + _dataStoreHelper.getResults(cursor, oCur.getFieldGetter(), results[cursor]); + dataStoreRequestCount++; + } + catch (GxADODataException e) + { + bool retry = false; + int retryCount = 0; + bool pe = oCur.Command.ProcessException(e, ref retry, retryCount, "FETCH"); + GXLogging.Error(log, "readNext Error", e); + if (!pe) + { + throw; + } + } + } public int getStatus(int cursorIdx) { diff --git a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs index 95163c45a..dac2b01d2 100644 --- a/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs +++ b/dotnet/src/dotnetframework/GxClasses/Data/GXDataNTierADO.cs @@ -834,8 +834,12 @@ public Cursor(string name, string stmt, GxErrorMask nmask, ICollection parmBinds { _staticParameters = staticPars; } + internal GxCommand Command + { + get { return _gxDbCommand; } + } - public void createCursor(IGxDataStore ds, GxErrorHandler errorHandler) + public void createCursor(IGxDataStore ds, GxErrorHandler errorHandler) { if (_state >= 2) @@ -1192,37 +1196,22 @@ public override void execute() _status = Cursor.EOF; _closed = false; } - public override void readNext() - { - if (_state < 2) - throw (new GxADODataException("Could not readNext in ForEachCursor:" + _name + ".")); - _status = 0; + public override void readNext() + { + if (_state < 2) + throw (new GxADODataException("Could not readNext in ForEachCursor:" + _name + ".")); + _status = 0; - try + if (!_DR.Read()) { - if (!_DR.Read()) - { - _status = Cursor.EOF; - _gxDbCommand.HasMoreRows = false; - } - else if (_gxDbCommand.Status == 1 || _gxDbCommand.Status == 103 || _gxDbCommand.Status == 500) - { - _status = _gxDbCommand.Status; - } + _status = Cursor.EOF; + _gxDbCommand.HasMoreRows = false; } - catch (GxADODataException e) + else if (_gxDbCommand.Status == 1 || _gxDbCommand.Status == 103 || _gxDbCommand.Status == 500) { - bool retry = false; - int retryCount = 0; - bool pe = _gxDbCommand.ProcessException(e, ref retry, retryCount, "FETCH"); - GXLogging.Error(log, "readNext Error", e); - if (!pe) - { - throw; - } + _status = _gxDbCommand.Status; } - } } public class UpdateCursor : Cursor