@@ -64,17 +64,21 @@ public async IAsyncEnumerable<T> QueryAsync(string? filter = null) {
6464 /// Inserts the entity into table storage.
6565 /// If successful, updates the ETag of the passed-in entity.
6666 public async Task < ResultVoid < ( HttpStatusCode Status , string Reason ) > > Insert ( T entity ) {
67- var tableClient = await GetTableClient ( typeof ( T ) . Name ) ;
68- var tableEntity = _entityConverter . ToTableEntity ( entity ) ;
69- var response = await tableClient . AddEntityAsync ( tableEntity ) ;
67+ try {
68+ var tableClient = await GetTableClient ( typeof ( T ) . Name ) ;
69+ var tableEntity = _entityConverter . ToTableEntity ( entity ) ;
70+ var response = await tableClient . AddEntityAsync ( tableEntity ) ;
7071
7172
72- if ( response . IsError ) {
73- return ResultVoid < ( HttpStatusCode , string ) > . Error ( ( ( HttpStatusCode ) response . Status , response . ReasonPhrase ) ) ;
74- } else {
75- // update ETag on success
76- entity . ETag = response . Headers . ETag ;
77- return ResultVoid < ( HttpStatusCode , string ) > . Ok ( ) ;
73+ if ( response . IsError ) {
74+ return ResultVoid < ( HttpStatusCode , string ) > . Error ( ( ( HttpStatusCode ) response . Status , response . ReasonPhrase ) ) ;
75+ } else {
76+ // update ETag on success
77+ entity . ETag = response . Headers . ETag ;
78+ return ResultVoid < ( HttpStatusCode , string ) > . Ok ( ) ;
79+ }
80+ } catch ( RequestFailedException ex ) {
81+ return ResultVoid < ( HttpStatusCode , string ) > . Error ( ( ( HttpStatusCode ) ex . Status , ex . Message ) ) ;
7882 }
7983 }
8084
@@ -100,16 +104,20 @@ public async IAsyncEnumerable<T> QueryAsync(string? filter = null) {
100104 throw new ArgumentException ( "ETag must be set when updating an entity" , nameof ( entity ) ) ;
101105 }
102106
103- var tableClient = await GetTableClient ( typeof ( T ) . Name ) ;
104- var tableEntity = _entityConverter . ToTableEntity ( entity ) ;
107+ try {
108+ var tableClient = await GetTableClient ( typeof ( T ) . Name ) ;
109+ var tableEntity = _entityConverter . ToTableEntity ( entity ) ;
105110
106- var response = await tableClient . UpdateEntityAsync ( tableEntity , entity . ETag . Value ) ;
107- if ( response . IsError ) {
108- return ResultVoid < ( HttpStatusCode , string ) > . Error ( ( ( HttpStatusCode ) response . Status , response . ReasonPhrase ) ) ;
109- } else {
110- // update ETag on success
111- entity . ETag = response . Headers . ETag ;
112- return ResultVoid < ( HttpStatusCode , string ) > . Ok ( ) ;
111+ var response = await tableClient . UpdateEntityAsync ( tableEntity , entity . ETag . Value ) ;
112+ if ( response . IsError ) {
113+ return ResultVoid < ( HttpStatusCode , string ) > . Error ( ( ( HttpStatusCode ) response . Status , response . ReasonPhrase ) ) ;
114+ } else {
115+ // update ETag on success
116+ entity . ETag = response . Headers . ETag ;
117+ return ResultVoid < ( HttpStatusCode , string ) > . Ok ( ) ;
118+ }
119+ } catch ( RequestFailedException ex ) {
120+ return ResultVoid < ( HttpStatusCode , string ) > . Error ( ( ( HttpStatusCode ) ex . Status , ex . Message ) ) ;
113121 }
114122 }
115123
@@ -127,13 +135,17 @@ public async Task<TableClient> GetTableClient(string table, ResourceIdentifier?
127135 }
128136
129137 public async Task < ResultVoid < ( HttpStatusCode Status , string Reason ) > > Delete ( T entity ) {
130- var tableClient = await GetTableClient ( typeof ( T ) . Name ) ;
131- var tableEntity = _entityConverter . ToTableEntity ( entity ) ;
132- var response = await tableClient . DeleteEntityAsync ( tableEntity . PartitionKey , tableEntity . RowKey ) ;
133- if ( response . IsError ) {
134- return ResultVoid < ( HttpStatusCode , string ) > . Error ( ( ( HttpStatusCode ) response . Status , response . ReasonPhrase ) ) ;
135- } else {
136- return ResultVoid < ( HttpStatusCode , string ) > . Ok ( ) ;
138+ try {
139+ var tableClient = await GetTableClient ( typeof ( T ) . Name ) ;
140+ var tableEntity = _entityConverter . ToTableEntity ( entity ) ;
141+ var response = await tableClient . DeleteEntityAsync ( tableEntity . PartitionKey , tableEntity . RowKey ) ;
142+ if ( response . IsError ) {
143+ return ResultVoid < ( HttpStatusCode , string ) > . Error ( ( ( HttpStatusCode ) response . Status , response . ReasonPhrase ) ) ;
144+ } else {
145+ return ResultVoid < ( HttpStatusCode , string ) > . Ok ( ) ;
146+ }
147+ } catch ( RequestFailedException ex ) {
148+ return ResultVoid < ( HttpStatusCode , string ) > . Error ( ( ( HttpStatusCode ) ex . Status , ex . Message ) ) ;
137149 }
138150 }
139151
@@ -150,13 +162,32 @@ public IAsyncEnumerable<T> SearchByTimeRange(DateTimeOffset min, DateTimeOffset
150162 return QueryAsync ( Query . TimeRange ( min , max ) ) ;
151163 }
152164
153- public async Task < List < ResultVoid < ( int , string ) > > > BatchOperation ( IAsyncEnumerable < T > entities , TableTransactionActionType actionType ) {
154- var tableClient = await GetTableClient ( typeof ( T ) . Name ) ;
155- var transactions = await entities . Select ( e => new TableTransactionAction ( actionType , _entityConverter . ToTableEntity ( e ) ) ) . ToListAsync ( ) ;
156- var responses = await tableClient . SubmitTransactionAsync ( transactions ) ;
157- return responses . Value . Select ( response =>
158- response . IsError ? ResultVoid < ( int , string ) > . Error ( ( response . Status , response . ReasonPhrase ) ) : ResultVoid < ( int , string ) > . Ok ( )
159- ) . ToList ( ) ;
165+ public async Task < ResultVoid < ( int statusCode , string reason , int ? failedTransactionIndex ) > > BatchOperation ( IAsyncEnumerable < T > entities , TableTransactionActionType actionType ) {
166+ try {
167+ var tableClient = await GetTableClient ( typeof ( T ) . Name ) ;
168+ var transactions = await entities . Select ( e => new TableTransactionAction ( actionType , _entityConverter . ToTableEntity ( e ) ) ) . ToListAsync ( ) ;
169+ var responses = await tableClient . SubmitTransactionAsync ( transactions ) ;
170+ var wrappingResponse = responses . GetRawResponse ( ) ;
171+ if ( wrappingResponse . IsError ) {
172+ return ResultVoid < ( int , string , int ? ) > . Error ( ( wrappingResponse . Status , wrappingResponse . ReasonPhrase , null ) ) ;
173+ }
174+
175+ var subTransactionFailures = responses . Value . Where ( response => response . IsError ) ;
176+ if ( subTransactionFailures . Any ( ) ) {
177+ var failedTransaction = subTransactionFailures . First ( ) ;
178+ var failedTransactionIndex = responses . Value . ToList ( ) . IndexOf ( failedTransaction ) ;
179+ return ResultVoid < ( int , string , int ? ) > . Error ( ( failedTransaction . Status , failedTransaction . ReasonPhrase , failedTransactionIndex ) ) ;
180+ }
181+
182+ return ResultVoid < ( int , string , int ? ) > . Ok ( ) ;
183+ } catch ( RequestFailedException ex ) {
184+ int ? failedTransactionIndex = null ;
185+ if ( ex is TableTransactionFailedException ttfex ) {
186+ failedTransactionIndex = ttfex . FailedTransactionActionIndex ;
187+ }
188+
189+ return ResultVoid < ( int , string , int ? ) > . Error ( ( ex . Status , ex . Message , failedTransactionIndex ) ) ;
190+ }
160191 }
161192
162193
0 commit comments