Skip to content

Commit 9b4627f

Browse files
authored
Update Invoke-CosmosDbReqiest to throw a CosmosDB.ResponseExeption instead of a HttpReponseException (#501)
* Refactor exception handling and enhance integration tests for Cosmos DB operations * Fix typo in ResponseException class name and update related test case * Add New-CosmosDbResponseException function and enhance ResponseException handling * Refactor tests for New-CosmosDbResponseException to use consistent variable naming and improve clarity * Refactor HttpResponseException tests for clarity and improve handling in PowerShell 7 environment * Refactor HttpResponseException tests to use script-scoped variables for improved clarity and consistency * Refactor test variable declarations for improved clarity and consistency * Refactor HttpResponseException tests for PowerShell 7 compatibility and improved clarity * Enhance build configuration by adding code coverage merging and updating coverage output settings * Update CHANGELOG and refactor exception handling in CosmosDB module - Document breaking change: Exceptions returned by Invoke-CosmosDbRequest are now CosmosDb.ResponseException objects. - Implement New-CosmosDbResponseException to handle exceptions more effectively. - Enhance integration tests to validate CosmosDb.ResponseException behavior for non-existent collections and documents. - Refactor unit tests to ensure proper handling of unsupported exception types. * Refactor New-CosmosDbResponseException to correctly assign status codes and update integration tests for improved accuracy * Update CHANGELOG and refactor CosmosDb.ResponseException handling to remove status code assignment and improve integration tests for clarity * Add verbose logging for CosmosDb.ResponseException handling in integration tests * Add verbose logging for CosmosDb.ResponseException handling in integration tests * Add verbose logging for exception handling in New-CosmosDbResponseException * Remove maxParallel setting from Unit and Integration Test Matrix jobs in azure-pipelines.yml * Improve message handling in New-CosmosDbResponseException and enhance verbose logging in integration tests * Refactor Cosmos DB response exception handling to differentiate error messages based on PowerShell edition
1 parent d95eea9 commit 9b4627f

File tree

10 files changed

+423
-61
lines changed

10 files changed

+423
-61
lines changed

CHANGELOG.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Changed
11+
12+
- BREAKING CHANGE: Exceptions returned by `Invoke-CosmosDbRequest` are now
13+
`CosmosDb.ResponseException` objects instead of either
14+
`Microsoft.PowerShell.Commands.HttpResponseException` (PowerShell 7.x) or
15+
`System.Net.HttpWebResponse` (PowerShell 5.x) objects. This is to prevent
16+
authorization Headers from being returned in the exception object. In future
17+
the filtered headers and other response information may be included in the
18+
`CosmosDb.ResponseException` object.
19+
1020
### Added
1121

1222
- Added `Get-CosmosDbRequestExceptionString` function to get the exception string
1323
from a Cosmos DB response. Refactored `Invoke-CosmosDbRequest` to use this
1424
function to get the exception string from the response.
15-
- Added testing for MacOS-13, MacOS-14, MacOS-15, Windows Server 2025, Ubuntu-24.04
16-
and PowerShell 7.x on Windows Server 2019, 2022 and 2025 to the CI pipeline.
1725

1826
### Fixed
1927

28+
- Added testing for MacOS-13, MacOS-14, MacOS-15, Windows Server 2025, Ubuntu-24.04
29+
and PowerShell 7.x on Windows Server 2019, 2022 and 2025 to the CI pipeline.
2030
- Converted CI pipeline Test stage to use matrix to reduce duplication of code.
2131
- FIx spelling error of `ApplicationObjectId` variable in CI pipeline.
2232

azure-pipelines.yml

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -67,66 +67,53 @@ stages:
6767
- job: Unit_Test_Matrix
6868
displayName: 'Unit Test Matrix'
6969
strategy:
70-
maxParallel: 5
7170
matrix:
7271
PS_Win2019:
7372
vmImage: windows-2019
74-
pesterScript: 'tests/Unit'
7573
testRunTitle: 'Unit (PowerShell 5.1 on Windows Server 2019)'
7674
pwsh: false
7775
PS_Win2022:
7876
vmImage: windows-2022
79-
pesterScript: 'tests/Unit'
8077
testRunTitle: 'Unit (PowerShell 5.1 on Windows Server 2022)'
8178
pwsh: false
8279
PS_Win2025:
8380
vmImage: windows-2025
84-
pesterScript: 'tests/Unit'
8581
testRunTitle: 'Unit (PowerShell 5.1 on Windows Server 2025)'
8682
pwsh: false
8783
PS7_Win2019:
8884
vmImage: windows-2019
89-
pesterScript: 'tests/Unit'
9085
testRunTitle: 'Unit (PowerShell 7 on Windows Server 2019)'
9186
pwsh: true
9287
PS7_Win2022:
9388
vmImage: windows-2022
94-
pesterScript: 'tests/Unit'
9589
testRunTitle: 'Unit (PowerShell 7 on Windows Server 2022)'
9690
pwsh: true
9791
PS7_Win2025:
9892
vmImage: windows-2025
99-
pesterScript: 'tests/Unit'
10093
testRunTitle: 'Unit (PowerShell 7 on Windows Server 2025)'
10194
pwsh: true
10295
PS7_Ubuntu2004:
10396
vmImage: ubuntu-20.04
104-
pesterScript: 'tests/Unit'
10597
testRunTitle: 'Unit (PowerShell 7 on Ubuntu 20.04)'
10698
pwsh: true
10799
PS7_Ubuntu2204:
108100
vmImage: ubuntu-22.04
109-
pesterScript: 'tests/Unit'
110101
testRunTitle: 'Unit (PowerShell 7 on Ubuntu 22.04)'
111102
pwsh: true
112103
PS7_Ubuntu2404:
113104
vmImage: ubuntu-24.04
114-
pesterScript: 'tests/Unit'
115105
testRunTitle: 'Unit (PowerShell 7 on Ubuntu 24.04)'
116106
pwsh: true
117107
PS7_MacOS13:
118108
vmImage: macos-13
119-
pesterScript: 'tests/Unit'
120109
testRunTitle: 'Unit (PowerShell 7 on MacOS 13)'
121110
pwsh: true
122111
PS7_MacOS14:
123112
vmImage: macos-14
124-
pesterScript: 'tests/Unit'
125113
testRunTitle: 'Unit (PowerShell 7 on MacOS 14)'
126114
pwsh: true
127115
PS7_MacOS15:
128116
vmImage: macos-15
129-
pesterScript: 'tests/Unit'
130117
testRunTitle: 'Unit (PowerShell 7 on MacOS 15)'
131118
pwsh: true
132119

@@ -152,7 +139,7 @@ stages:
152139
displayName: 'Run Unit Test'
153140
inputs:
154141
filePath: './build.ps1'
155-
arguments: "-tasks test -PesterScript '$(pesterScript)'"
142+
arguments: "-tasks test -PesterScript 'tests/Unit'"
156143
pwsh: $(pwsh)
157144

158145
- task: PublishTestResults@2
@@ -175,66 +162,53 @@ stages:
175162
displayName: 'Integration Test Matrix'
176163
dependsOn: Unit_Test_Matrix
177164
strategy:
178-
maxParallel: 5
179165
matrix:
180166
PS_Win2019:
181167
vmImage: windows-2019
182-
pesterScript: 'tests/Integration'
183168
testRunTitle: 'Integration (PowerShell 5.1 on Windows Server 2019)'
184169
pwsh: false
185170
PS_Win2022:
186171
vmImage: windows-2022
187-
pesterScript: 'tests/Integration'
188172
testRunTitle: 'Integration (PowerShell 5.1 on Windows Server 2022)'
189173
pwsh: false
190174
PS_Win2025:
191175
vmImage: windows-2025
192-
pesterScript: 'tests/Integration'
193176
testRunTitle: 'Integration (PowerShell 5.1 on Windows Server 2025)'
194177
pwsh: false
195178
PS7_Win2019:
196179
vmImage: windows-2019
197-
pesterScript: 'tests/Integration'
198180
testRunTitle: 'Integration (PowerShell 7 on Windows Server 2019)'
199181
pwsh: true
200182
PS7_Win2022:
201183
vmImage: windows-2022
202-
pesterScript: 'tests/Integration'
203184
testRunTitle: 'Integration (PowerShell 7 on Windows Server 2022)'
204185
pwsh: true
205186
PS7_Win2025:
206187
vmImage: windows-2025
207-
pesterScript: 'tests/Integration'
208188
testRunTitle: 'Integration (PowerShell 7 on Windows Server 2025)'
209189
pwsh: true
210190
PS7_Ubuntu2004:
211191
vmImage: ubuntu-20.04
212-
pesterScript: 'tests/Integration'
213192
testRunTitle: 'Integration (PowerShell 7 on Ubuntu 20.04)'
214193
pwsh: true
215194
PS7_Ubuntu2204:
216195
vmImage: ubuntu-22.04
217-
pesterScript: 'tests/Integration'
218196
testRunTitle: 'Integration (PowerShell 7 on Ubuntu 22.04)'
219197
pwsh: true
220198
PS7_Ubuntu2404:
221199
vmImage: ubuntu-24.04
222-
pesterScript: 'tests/Integration'
223200
testRunTitle: 'Integration (PowerShell 7 on Ubuntu 24.04)'
224201
pwsh: true
225202
PS7_MacOS13:
226203
vmImage: macos-13
227-
pesterScript: 'tests/Integration'
228204
testRunTitle: 'Integration (PowerShell 7 on MacOS 13)'
229205
pwsh: true
230206
PS7_MacOS14:
231207
vmImage: macos-14
232-
pesterScript: 'tests/Integration'
233208
testRunTitle: 'Integration (PowerShell 7 on MacOS 14)'
234209
pwsh: true
235210
PS7_MacOS15:
236211
vmImage: macos-15
237-
pesterScript: 'tests/Integration'
238212
testRunTitle: 'Integration (PowerShell 7 on MacOS 15)'
239213
pwsh: true
240214

@@ -259,7 +233,7 @@ stages:
259233
azureApplicationObjectId: $(azureApplicationObjectId)
260234
inputs:
261235
filePath: './build.ps1'
262-
arguments: "-Tasks test -PesterScript '$(pesterScript)' -CodeCoverageThreshold 0"
236+
arguments: "-Tasks test -PesterScript 'tests/Integration' -CodeCoverageThreshold 0"
263237
pwsh: $(pwsh)
264238

265239
- task: PublishTestResults@2

build.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ BuildWorkflow:
8080
- Pester_Tests_Stop_On_Fail
8181
- Pester_if_Code_Coverage_Under_Threshold
8282

83+
merge:
84+
- Merge_CodeCoverage_Files
85+
8386
publish:
8487
- Publish_Release_To_GitHub
8588
- Publish_Module_To_gallery
@@ -115,7 +118,18 @@ TaskHeader: |
115118
""
116119
117120
####################################################
118-
# PESTER Configuration #
121+
# Code Coverage Configuration #
122+
####################################################
123+
124+
CodeCoverage:
125+
# Filename of the file that will be outputted by the task Merge_CodeCoverage_Files.
126+
CodeCoverageMergedOutputFile: JaCoCo_coverage.xml
127+
# File pattern used to search for files under the ./output/testResults folder
128+
# by task Merge_CodeCoverage_Files.
129+
CodeCoverageFilePattern: Codecov*.xml
130+
131+
####################################################
132+
# Pester Configuration #
119133
####################################################
120134
Pester:
121135
OutputFormat: NUnitXML

source/Private/utils/Invoke-CosmosDbRequest.ps1

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,11 @@ function Invoke-CosmosDbRequest
251251
}
252252
catch [System.Net.WebException], [Microsoft.PowerShell.Commands.HttpResponseException]
253253
{
254+
<#
255+
When a response exception is thrown by Invoke-WebRequest:
256+
PowerShell 5.x throws System.Net.WebException
257+
PowerShell 7.x throws Microsoft.PowerShell.Commands.HttpResponseException
258+
#>
254259
if ($_.Exception.Response.StatusCode -eq 429)
255260
{
256261
<#
@@ -289,11 +294,6 @@ function Invoke-CosmosDbRequest
289294

290295
if ($_.Exception.Response)
291296
{
292-
<#
293-
Write out additional exception information into the verbose stream
294-
In a future version a custom exception type for CosmosDB that
295-
contains this additional information.
296-
#>
297297
$exceptionResponse = Get-CosmosDbRequestExceptionString -ErrorRecord $_
298298

299299
if ($exceptionResponse)
@@ -305,14 +305,15 @@ function Invoke-CosmosDbRequest
305305
# A non-recoverable exception occurred
306306
$fatal = $true
307307

308-
Throw $_
308+
throw (New-CosmosDbResponseException -InputObject $_.Exception)
309309
}
310+
310311
catch
311312
{
312313
# A non-recoverable exception occurred
313314
$fatal = $true
314315

315-
Throw $_
316+
throw (New-CosmosDbResponseException -InputObject $_.Exception)
316317
}
317318
} while ($requestComplete -eq $false -and -not $fatal)
318319

source/Private/utils/New-CosmosDbInvalidOperationException.ps1

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,13 @@ function New-CosmosDbInvalidOperationException
2222
elseif ($null -eq $ErrorRecord)
2323
{
2424
$invalidOperationException =
25-
New-Object -TypeName 'InvalidOperationException' -ArgumentList @( $Message )
25+
New-Object -TypeName 'InvalidOperationException' -ArgumentList @( $Message )
2626
}
2727
else
2828
{
2929
$invalidOperationException =
30-
New-Object -TypeName 'InvalidOperationException' -ArgumentList @( $Message,
31-
$ErrorRecord.Exception )
30+
New-Object -TypeName 'InvalidOperationException' -ArgumentList @( $Message,
31+
$ErrorRecord.Exception )
3232
}
3333

3434
$newObjectParams = @{
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
function New-CosmosDbResponseException
2+
{
3+
[CmdletBinding()]
4+
[OutputType([CosmosDB.ResponseException])]
5+
param
6+
(
7+
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
8+
[ValidateNotNull()]
9+
[Alias('Exception')]
10+
[System.Exception]
11+
$InputObject
12+
)
13+
14+
process
15+
{
16+
$message = $InputObject.Message
17+
18+
switch ($InputObject)
19+
{
20+
{ $_ -is [Microsoft.PowerShell.Commands.HttpResponseException] }
21+
{
22+
Write-Verbose -Message $($LocalizedData.NewCosmosDbResponseExceptionHttpResponseExceptionMessage -f $message)
23+
# PowerShell 7.0+ - just use the message
24+
}
25+
26+
{ $_ -is [System.Net.WebException] }
27+
{
28+
Write-Verbose -Message $($LocalizedData.NewCosmosDbResponseExceptionWebException -f $message)
29+
# PowerShell 5.1 - attempt to use the message in the Response
30+
$webResponse = $InputObject.Response
31+
if ($webResponse -is [System.Net.HttpWebResponse])
32+
{
33+
if ($null -ne $WebRespons.Message)
34+
{
35+
$message = $webResponse.Message
36+
}
37+
}
38+
}
39+
40+
default {
41+
Write-Verbose -Message $($LocalizedData.NewCosmosDbResponseExceptionDefaultException -f $message)
42+
# Other exception types don't set any other properties
43+
}
44+
}
45+
46+
$responseException = [CosmosDB.ResponseException]::new($message)
47+
return $responseException
48+
}
49+
}

0 commit comments

Comments
 (0)