Skip to content

Commit 9c6d69f

Browse files
Improve parsing of AWS errors (#253)
* Improve parsing of AWS errors * Fix github runner issue * Broaden DownloadFile() status code handling * Add assert to missing file test * Small test format fix * PubNub SDK v7.3.13.0 release. --------- Co-authored-by: PubNub Release Bot <[email protected]>
1 parent 42bc6a5 commit 9c6d69f

File tree

13 files changed

+93
-124
lines changed

13 files changed

+93
-124
lines changed

.github/workflows/release/build-packages.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ dotnet pack -o "$RELEASES_PATH\PCL" -c Release
2424
# Build UWP package.
2525
echo "Build UWP package"
2626
cd "$githubWorkspace\src\Api\PubnubApiUWP"
27-
dotnet restore
27+
dotnet restore /p:BuildWithNetFrameworkHostedCompiler=true
2828
msbuild PubnubApiUWP.csproj /t:Pack /p:Configuration=Release /p:PackageOutputPath="$RELEASES_PATH\UWP" /v:n
2929

3030
echo "Copy built packages"

.github/workflows/run-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
with:
7878
dotnet-version: 6.0.x
7979
- name: Restore dependencies
80-
run: dotnet restore
80+
run: dotnet restore /p:BuildWithNetFrameworkHostedCompiler=true
8181
- name: Build Projects
8282
run: |
8383
cd ./UnitTests/AcceptanceTests

.pubnub.yml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
name: c-sharp
2-
version: "7.3.12"
2+
version: "7.3.13"
33
schema: 1
44
scm: github.com/pubnub/c-sharp
55
changelog:
6+
- date: 2025-06-06
7+
version: v7.3.13
8+
changes:
9+
- type: bug
10+
text: "Improved parsing of file download errors to be properly set in operation status ErrorData."
611
- date: 2025-05-28
712
version: v7.3.12
813
changes:
@@ -909,7 +914,7 @@ features:
909914
- QUERY-PARAM
910915
supported-platforms:
911916
-
912-
version: Pubnub 'C#' 7.3.12
917+
version: Pubnub 'C#' 7.3.13
913918
platforms:
914919
- Windows 10 and up
915920
- Windows Server 2008 and up
@@ -920,7 +925,7 @@ supported-platforms:
920925
- .Net Framework 4.6.1+
921926
- .Net Framework 6.0
922927
-
923-
version: PubnubPCL 'C#' 7.3.12
928+
version: PubnubPCL 'C#' 7.3.13
924929
platforms:
925930
- Xamarin.Android
926931
- Xamarin.iOS
@@ -940,7 +945,7 @@ supported-platforms:
940945
- .Net Core
941946
- .Net 6.0
942947
-
943-
version: PubnubUWP 'C#' 7.3.12
948+
version: PubnubUWP 'C#' 7.3.13
944949
platforms:
945950
- Windows Phone 10
946951
- Universal Windows Apps
@@ -964,7 +969,7 @@ sdks:
964969
distribution-type: source
965970
distribution-repository: GitHub
966971
package-name: Pubnub
967-
location: https://github.com/pubnub/c-sharp/releases/tag/v7.3.12.0
972+
location: https://github.com/pubnub/c-sharp/releases/tag/v7.3.13.0
968973
requires:
969974
-
970975
name: ".Net"
@@ -1247,7 +1252,7 @@ sdks:
12471252
distribution-type: source
12481253
distribution-repository: GitHub
12491254
package-name: PubNubPCL
1250-
location: https://github.com/pubnub/c-sharp/releases/tag/v7.3.12.0
1255+
location: https://github.com/pubnub/c-sharp/releases/tag/v7.3.13.0
12511256
requires:
12521257
-
12531258
name: ".Net Core"
@@ -1606,7 +1611,7 @@ sdks:
16061611
distribution-type: source
16071612
distribution-repository: GitHub
16081613
package-name: PubnubUWP
1609-
location: https://github.com/pubnub/c-sharp/releases/tag/v7.3.12.0
1614+
location: https://github.com/pubnub/c-sharp/releases/tag/v7.3.13.0
16101615
requires:
16111616
-
16121617
name: "Universal Windows Platform Development"

CHANGELOG

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
v7.3.13 - June 06 2025
2+
-----------------------------
3+
- Fixed: improved parsing of file download errors to be properly set in operation status ErrorData.
4+
15
v7.3.12 - May 28 2025
26
-----------------------------
37
- Added: added new integration tests to better cover all SDK endpoints.

src/Api/PubnubApi/EndPoint/Files/DownloadFileOperation.cs

Lines changed: 32 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
34
using System.Globalization;
45
using System.Threading.Tasks;
6+
using System.Xml.Linq;
57
using PubnubApi.Security.Crypto;
68
using PubnubApi.Security.Crypto.Cryptors;
79

@@ -91,83 +93,11 @@ internal void Retry()
9193

9294
private void ProcessFileDownloadRequest(PNCallback<PNDownloadFileResult> callback)
9395
{
94-
RequestState<PNDownloadFileResult> requestState = new RequestState<PNDownloadFileResult>
95-
{
96-
ResponseType = PNOperationType.PNDownloadFileOperation,
97-
PubnubCallback = callback,
98-
Reconnect = false,
99-
EndPointOperation = this
100-
};
101-
102-
var requestParameter = CreateRequestParameter();
103-
var transportRequest = PubnubInstance.transportMiddleware.PreapareTransportRequest(
104-
requestParameter: requestParameter, operationType: PNOperationType.PNDownloadFileOperation);
105-
PubnubInstance.transportMiddleware.Send(transportRequest: transportRequest).ContinueWith(t =>
96+
var processTask = ProcessFileDownloadRequest();
97+
processTask.ContinueWith((t) =>
10698
{
107-
var transportResponse = t.Result;
108-
if (transportResponse.Error == null)
109-
{
110-
var fileContentBytes = transportResponse.Content;
111-
if (fileContentBytes != null)
112-
{
113-
requestState.GotJsonResponse = true;
114-
byte[] outputBytes;
115-
if (string.IsNullOrEmpty(currentFileCipherKey) && string.IsNullOrEmpty(config.CipherKey) &&
116-
config.CryptoModule == null)
117-
{
118-
outputBytes = fileContentBytes;
119-
}
120-
else
121-
{
122-
CryptoModule currentCryptoModule = !string.IsNullOrEmpty(currentFileCipherKey)
123-
? new CryptoModule(new LegacyCryptor(currentFileCipherKey, true, config.Logger), null)
124-
: (config.CryptoModule ??=
125-
new CryptoModule(new LegacyCryptor(config.CipherKey, true), null));
126-
try
127-
{
128-
outputBytes = currentCryptoModule.Decrypt(fileContentBytes);
129-
logger?.Debug($"Stream length (after Decrypt)= {fileContentBytes.Length}");
130-
}
131-
catch (Exception ex)
132-
{
133-
logger?.Error(
134-
$" Error while decrypting file content.File might be not encrypted, returning as it is. exception: {ex}");
135-
outputBytes = fileContentBytes;
136-
}
137-
}
138-
139-
PNDownloadFileResult result = new PNDownloadFileResult
140-
{
141-
FileBytes = outputBytes,
142-
FileName = currentFileName
143-
};
144-
PNStatus status = new StatusBuilder(config, jsonLibrary).CreateStatusResponse(
145-
requestState.ResponseType, PNStatusCategory.PNAcknowledgmentCategory, requestState, 200,
146-
null);
147-
callback.OnResponse(result, status);
148-
logger?.Info($"{GetType().Name} request finished with status code {status?.StatusCode}");
149-
}
150-
else
151-
{
152-
PNStatus errorStatus = GetStatusIfError(requestState, null);
153-
154-
callback.OnResponse(default, errorStatus);
155-
logger?.Info(
156-
$"{GetType().Name} request finished with status code {requestState.Response?.StatusCode}");
157-
}
158-
}
159-
else
160-
{
161-
int statusCode = PNStatusCodeHelper.GetHttpStatusCode(transportResponse.Error.Message);
162-
PNStatusCategory category =
163-
PNStatusCategoryHelper.GetPNStatusCategory(statusCode, transportResponse.Error.Message);
164-
PNStatus status = new StatusBuilder(config, jsonLibrary).CreateStatusResponse(
165-
PNOperationType.PNDownloadFileOperation, category, requestState, statusCode,
166-
new PNException(transportResponse.Error.Message, transportResponse.Error));
167-
requestState.PubnubCallback.OnResponse(default, status);
168-
logger?.Info(
169-
$"{GetType().Name} request finished with status code {requestState.Response?.StatusCode}");
170-
}
99+
var result = t.Result;
100+
callback.OnResponse(result.Result, result.Status);
171101
});
172102
}
173103

@@ -198,17 +128,18 @@ private async Task<PNResult<PNDownloadFileResult>> ProcessFileDownloadRequest()
198128
}
199129

200130
logger?.Debug($"{GetType().Name} parameter validated.");
131+
var requestParameter = CreateRequestParameter();
132+
var transportRequest = PubnubInstance.transportMiddleware.PreapareTransportRequest(
133+
requestParameter: requestParameter, operationType: PNOperationType.PNDownloadFileOperation);
134+
var transportResponse = await PubnubInstance.transportMiddleware.Send(transportRequest: transportRequest)
135+
.ConfigureAwait(false);
201136
RequestState<PNDownloadFileResult> requestState = new RequestState<PNDownloadFileResult>
202137
{
203138
ResponseType = PNOperationType.PNDownloadFileOperation,
139+
Response = transportResponse,
204140
Reconnect = false,
205141
EndPointOperation = this
206142
};
207-
var requestParameter = CreateRequestParameter();
208-
var transportRequest = PubnubInstance.transportMiddleware.PreapareTransportRequest(
209-
requestParameter: requestParameter, operationType: PNOperationType.PNDownloadFileOperation);
210-
var transportResponse = await PubnubInstance.transportMiddleware.Send(transportRequest: transportRequest)
211-
.ConfigureAwait(false);
212143
if (transportResponse.Error == null)
213144
{
214145
var fileContentBytes = transportResponse.Content;
@@ -241,17 +172,27 @@ private async Task<PNResult<PNDownloadFileResult>> ProcessFileDownloadRequest()
241172
{ Error = true, ErrorData = new PNErrorData("Decryption error", ex) };
242173
}
243174
}
244-
245-
PNStatus status = new StatusBuilder(config, jsonLibrary).CreateStatusResponse(
246-
requestState.ResponseType, PNStatusCategory.PNAcknowledgmentCategory, requestState,
247-
transportResponse.StatusCode, null);
248-
PNDownloadFileResult result = new PNDownloadFileResult
175+
176+
//Parsing for AWS errors (httpClient doesn't throw an exception but returns a 4xx status code with error in body)
177+
if (transportResponse.StatusCode is >= 400 and < 500)
249178
{
250-
FileBytes = outputBytes,
251-
FileName = currentFileName
252-
};
253-
returnValue.Result = result;
254-
returnValue.Status = status;
179+
var stringResult = System.Text.Encoding.UTF8.GetString(outputBytes);
180+
PNStatus errorStatus = GetStatusIfError(requestState, stringResult);
181+
returnValue.Status = errorStatus;
182+
}
183+
else
184+
{
185+
PNStatus status = new StatusBuilder(config, jsonLibrary).CreateStatusResponse(
186+
requestState.ResponseType, PNStatusCategory.PNAcknowledgmentCategory, requestState,
187+
transportResponse.StatusCode, null);
188+
PNDownloadFileResult result = new PNDownloadFileResult
189+
{
190+
FileBytes = outputBytes,
191+
FileName = currentFileName
192+
};
193+
returnValue.Result = result;
194+
returnValue.Status = status;
195+
}
255196
}
256197
else
257198
{

src/Api/PubnubApi/Properties/AssemblyInfo.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
[assembly: AssemblyProduct("Pubnub C# SDK")]
1212
[assembly: AssemblyCopyright("Copyright © 2021")]
1313
[assembly: AssemblyTrademark("")]
14-
[assembly: AssemblyVersion("7.3.12.0")]
15-
[assembly: AssemblyFileVersion("7.3.12.0")]
14+
[assembly: AssemblyVersion("7.3.13.0")]
15+
[assembly: AssemblyFileVersion("7.3.13.0")]
1616
// Setting ComVisible to false makes the types in this assembly not visible
1717
// to COM components. If you need to access a type in this assembly from
1818
// COM, set the ComVisible attribute to true on that type.

src/Api/PubnubApi/PubnubApi.csproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,15 @@
1414

1515
<PropertyGroup>
1616
<PackageId>Pubnub</PackageId>
17-
<PackageVersion>7.3.12.0</PackageVersion>
17+
<PackageVersion>7.3.13.0</PackageVersion>
1818
<Title>PubNub C# .NET - Web Data Push API</Title>
1919
<Authors>Pandu Masabathula</Authors>
2020
<Owners>PubNub</Owners>
2121
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
2222
<PackageIconUrl>http://pubnub.s3.amazonaws.com/2011/powered-by-pubnub/pubnub-icon-600x600.png</PackageIconUrl>
2323
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
2424
<RepositoryUrl>https://github.com/pubnub/c-sharp/</RepositoryUrl>
25-
<PackageReleaseNotes>Fixed an issue when upon receiving a message with published with a custom type the CustomMessageType would be null upon receiving.
26-
Added new integration tests to better cover all SDK endpoints.</PackageReleaseNotes>
25+
<PackageReleaseNotes>Improved parsing of file download errors to be properly set in operation status ErrorData.</PackageReleaseNotes>
2726
<PackageTags>Web Data Push Real-time Notifications ESB Message Broadcasting Distributed Computing</PackageTags>
2827
<!--<Summary>PubNub is a Massively Scalable Web Push Service for Web and Mobile Games. This is a cloud-based service for broadcasting messages to thousands of web and mobile clients simultaneously</Summary>-->
2928
<Description>PubNub is a Massively Scalable Web Push Service for Web and Mobile Games. This is a cloud-based service for broadcasting messages to thousands of web and mobile clients simultaneously</Description>

src/Api/PubnubApi/PubnubCoreBase.cs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
using PubnubApi.Security.Crypto;
1414
using PubnubApi.Security.Crypto.Cryptors;
1515
using System.Collections.Concurrent;
16+
using System.Xml.Linq;
17+
1618
#endregion
1719

1820
namespace PubnubApi
@@ -1069,11 +1071,31 @@ protected PNStatus GetStatusIfError<T>(RequestState<T> asyncRequestState, string
10691071
{
10701072
if (pubnubConfig.TryGetValue(PubnubInstance.InstanceId, out currentConfig))
10711073
{
1072-
string message = ExtractValue(jsonString, "<Message>", "</Message>");
1073-
string proposedSize = ExtractValue(jsonString, "<ProposedSize>", "</ProposedSize>");
1074-
var errorMessage = string.IsNullOrEmpty((message)) ? jsonString : $"File upload failed: {message}";
1075-
errorMessage+= string.IsNullOrEmpty(proposedSize)?"":$", maximum allowed size is {proposedSize}";
1076-
status = new StatusBuilder(currentConfig, jsonLib).CreateStatusResponse<T>(type, PNStatusCategory.PNUnknownCategory, asyncRequestState, Constants.HttpRequestEntityTooLargeStatusCode, new PNException(errorMessage));
1074+
var parsedXml = XDocument.Parse(jsonString);
1075+
var errorElement = parsedXml.Root;
1076+
var errorMessage = string.Empty;
1077+
if (errorElement?.Name == "Error")
1078+
{
1079+
var code = errorElement.Element("Code");
1080+
if (code != null)
1081+
{
1082+
errorMessage += $"Code: {code.Value} ";
1083+
}
1084+
var message = errorElement.Element("Message");
1085+
if (message != null)
1086+
{
1087+
errorMessage += $"Message: {message.Value} ";
1088+
}
1089+
var proposedSize = errorElement.Element("ProposedSize");
1090+
if (proposedSize != null)
1091+
{
1092+
errorMessage += $"Maximum allowed size is: {proposedSize.Value} ";
1093+
}
1094+
}
1095+
errorMessage = string.IsNullOrEmpty((errorMessage)) ? jsonString : errorMessage;
1096+
//TODO: might not always be applicable
1097+
var statusCode = asyncRequestState?.Response?.StatusCode ?? Constants.HttpRequestEntityTooLargeStatusCode;
1098+
status = new StatusBuilder(currentConfig, jsonLib).CreateStatusResponse<T>(type, PNStatusCategory.PNUnknownCategory, asyncRequestState, statusCode, new PNException(errorMessage));
10771099
}
10781100
}
10791101

src/Api/PubnubApiPCL/PubnubApiPCL.csproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,15 @@
1414

1515
<PropertyGroup>
1616
<PackageId>PubnubPCL</PackageId>
17-
<PackageVersion>7.3.12.0</PackageVersion>
17+
<PackageVersion>7.3.13.0</PackageVersion>
1818
<Title>PubNub C# .NET - Web Data Push API</Title>
1919
<Authors>Pandu Masabathula</Authors>
2020
<Owners>PubNub</Owners>
2121
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
2222
<PackageIconUrl>http://pubnub.s3.amazonaws.com/2011/powered-by-pubnub/pubnub-icon-600x600.png</PackageIconUrl>
2323
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
2424
<RepositoryUrl>https://github.com/pubnub/c-sharp/</RepositoryUrl>
25-
<PackageReleaseNotes>Fixed an issue when upon receiving a message with published with a custom type the CustomMessageType would be null upon receiving.
26-
Added new integration tests to better cover all SDK endpoints.</PackageReleaseNotes>
25+
<PackageReleaseNotes>Improved parsing of file download errors to be properly set in operation status ErrorData.</PackageReleaseNotes>
2726
<PackageTags>Web Data Push Real-time Notifications ESB Message Broadcasting Distributed Computing</PackageTags>
2827
<!--<Summary>PubNub is a Massively Scalable Web Push Service for Web and Mobile Games. This is a cloud-based service for broadcasting messages to thousands of web and mobile clients simultaneously</Summary>-->
2928
<Description>PubNub is a Massively Scalable Web Push Service for Web and Mobile Games. This is a cloud-based service for broadcasting messages to thousands of web and mobile clients simultaneously</Description>

src/Api/PubnubApiUWP/PubnubApiUWP.csproj

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,15 @@
1616

1717
<PropertyGroup>
1818
<PackageId>PubnubUWP</PackageId>
19-
<PackageVersion>7.3.12.0</PackageVersion>
19+
<PackageVersion>7.3.13.0</PackageVersion>
2020
<Title>PubNub C# .NET - Web Data Push API</Title>
2121
<Authors>Pandu Masabathula</Authors>
2222
<Owners>PubNub</Owners>
2323
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
2424
<PackageIconUrl>http://pubnub.s3.amazonaws.com/2011/powered-by-pubnub/pubnub-icon-600x600.png</PackageIconUrl>
2525
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
2626
<RepositoryUrl>https://github.com/pubnub/c-sharp/</RepositoryUrl>
27-
<PackageReleaseNotes>Fixed an issue when upon receiving a message with published with a custom type the CustomMessageType would be null upon receiving.
28-
Added new integration tests to better cover all SDK endpoints.</PackageReleaseNotes>
27+
<PackageReleaseNotes>Improved parsing of file download errors to be properly set in operation status ErrorData.</PackageReleaseNotes>
2928
<PackageTags>Web Data Push Real-time Notifications ESB Message Broadcasting Distributed Computing</PackageTags>
3029
<!--<Summary>PubNub is a Massively Scalable Web Push Service for Web and Mobile Games. This is a cloud-based service for broadcasting messages to thousands of web and mobile clients simultaneously</Summary>-->
3130
<Description>PubNub is a Massively Scalable Web Push Service for Web and Mobile Games. This is a cloud-based service for broadcasting messages to thousands of web and mobile clients simultaneously</Description>

0 commit comments

Comments
 (0)