Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Page API fix: Load Page Type correctly to fix page header removal #1692 [A-Murchison - Adam Murchison]
- Admin library: Apps and service principals that were used with sites.selected scopes/roles were wrongly flagged as ACS principals
- Fix File.Approve method to work properly. It was doing the checkin operation instead. #1712 [gautamdsheth - Gautam Sheth]
- Fixed folder not found errors to DirectoryNotFoundException. #1725 [ejazhussain - Ejaz Hussain]

## [1.15]

Expand Down
65 changes: 65 additions & 0 deletions src/sdk/PnP.Core.Test/SharePoint/FoldersTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1409,5 +1409,70 @@ private async Task CleanupMockFolderFromRecycleBin(PnPContext context, Guid recy
}

#endregion

#region Issue 1722 - GetFolder* methods throw wrong error

[TestMethod]
[ExpectedException(typeof(SharePointRestServiceException))]
public async Task GetFolderByServerRelativeUrl_NonExistentFolder_ShouldThrowCorrectException()
{
//TestCommon.Instance.Mocking = false;
using (var context = await TestCommon.Instance.GetContextAsync(TestCommon.NoGroupTestSite))
{
string nonExistentFolderUrl = $"{context.Uri.PathAndQuery}/NonExistentFolder12345";

try
{
// This should throw an exception because the folder doesn't exist
var folder = await context.Web.GetFolderByServerRelativeUrlAsync(nonExistentFolderUrl);
}
catch (Exception ex)
{
Console.WriteLine($"Exception Type: {ex.GetType().FullName}");
Console.WriteLine($"Exception Message: {ex.Message}");
if (ex is PnPException pnpEx && pnpEx.Error is SharePointRestError spError)
{
Console.WriteLine($"Error Message: {spError.Message}");
Console.WriteLine($"Error Code: {spError.Code}");
Console.WriteLine($"Server Error Code: {spError.ServerErrorCode}");
Console.WriteLine($"HTTP Response Code: {spError.HttpResponseCode}");
}
throw;
}
}
}

[TestMethod]
[ExpectedException(typeof(SharePointRestServiceException))]
public async Task GetFolderById_NonExistentFolder_ShouldThrowCorrectException()
{
//TestCommon.Instance.Mocking = false;
using (var context = await TestCommon.Instance.GetContextAsync(TestCommon.NoGroupTestSite))
{
// Use a random GUID that doesn't exist
Guid nonExistentFolderId = Guid.NewGuid();

try
{
// This should throw an exception because the folder doesn't exist
var folder = await context.Web.GetFolderByIdAsync(nonExistentFolderId);
}
catch (Exception ex)
{
Console.WriteLine($"Exception Type: {ex.GetType().FullName}");
Console.WriteLine($"Exception Message: {ex.Message}");
if (ex is PnPException pnpEx && pnpEx.Error is SharePointRestError spError)
{
Console.WriteLine($"Error Message: {spError.Message}");
Console.WriteLine($"Error Code: {spError.Code}");
Console.WriteLine($"Server Error Code: {spError.ServerErrorCode}");
Console.WriteLine($"HTTP Response Code: {spError.HttpResponseCode}");
}
throw;
}
}
}

#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"IsSuccessStatusCode":true,"StatusCode":200,"Headers":{"SPRequestGuid":"2884f2a1-60ce-f000-6d2c-b32d16c7e3e4","SPClientServiceRequestDuration":"21","X-SharePointHealthScore":"0","X-SP-SERVERSTATE":"ReadOnly=0"},"Response":"{\u0022RegionalSettings\u0022:{\u0022TimeZone\u0022:{\u0022Description\u0022:\u0022(UTC-08:00) Pacific Time (US and Canada)\u0022,\u0022Id\u0022:13,\u0022Information\u0022:{\u0022Bias\u0022:480,\u0022DaylightBias\u0022:-60,\u0022StandardBias\u0022:0}},\u0022AdjustHijriDays\u0022:0,\u0022AlternateCalendarType\u0022:0,\u0022AM\u0022:\u0022AM\u0022,\u0022CalendarType\u0022:1,\u0022Collation\u0022:25,\u0022CollationLCID\u0022:2070,\u0022DateFormat\u0022:0,\u0022DateSeparator\u0022:\u0022/\u0022,\u0022DecimalSeparator\u0022:\u0022.\u0022,\u0022DigitGrouping\u0022:\u00223;0\u0022,\u0022FirstDayOfWeek\u0022:0,\u0022FirstWeekOfYear\u0022:0,\u0022IsEastAsia\u0022:false,\u0022IsRightToLeft\u0022:false,\u0022IsUIRightToLeft\u0022:false,\u0022ListSeparator\u0022:\u0022,\u0022,\u0022LocaleId\u0022:1033,\u0022NegativeSign\u0022:\u0022-\u0022,\u0022NegNumberMode\u0022:1,\u0022PM\u0022:\u0022PM\u0022,\u0022PositiveSign\u0022:\u0022\u0022,\u0022ShowWeeks\u0022:false,\u0022ThousandSeparator\u0022:\u0022,\u0022,\u0022Time24\u0022:false,\u0022TimeMarkerPosition\u0022:0,\u0022TimeSeparator\u0022:\u0022:\u0022,\u0022WorkDayEndHour\u0022:1020,\u0022WorkDays\u0022:62,\u0022WorkDayStartHour\u0022:480},\u0022Id\u0022:\u00220299607f-1525-4d06-9f59-76a814d85b0d\u0022,\u0022Url\u0022:\u0022https://ejazhussain.sharepoint.com/sites/pnpcoresdktest\u0022}"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"IsSuccessStatusCode":true,"StatusCode":200,"Headers":{"SPRequestGuid":"2884f2a1-a0d8-f000-3a2b-5319bbd88cef","SPClientServiceRequestDuration":"8","X-SharePointHealthScore":"1","X-SP-SERVERSTATE":"ReadOnly=0"},"Response":"{\u0022GroupId\u0022:\u002200000000-0000-0000-0000-000000000000\u0022,\u0022Id\u0022:\u0022dc9ac6af-e7e8-4ae3-88e1-e158b99dd3d0\u0022}"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"IsSuccessStatusCode":false,"StatusCode":404,"Headers":{"SPRequestGuid":"2884f2a1-90dd-f000-6d2c-b8c237347733","SPClientServiceRequestDuration":"14","X-SharePointHealthScore":"3","X-SP-SERVERSTATE":"ReadOnly=0"},"Response":"{\u0022odata.error\u0022:{\u0022code\u0022:\u0022-2147024894, System.IO.FileNotFoundException\u0022,\u0022message\u0022:{\u0022lang\u0022:\u0022en-US\u0022,\u0022value\u0022:\u0022File Not Found.\u0022}}}"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"IsSuccessStatusCode":true,"StatusCode":200,"Headers":{"SPRequestGuid":"3c84f2a1-4025-f000-3a2b-5c64f2f2c87e","SPClientServiceRequestDuration":"11","X-SharePointHealthScore":"2","X-SP-SERVERSTATE":"ReadOnly=0"},"Response":"{\u0022RegionalSettings\u0022:{\u0022TimeZone\u0022:{\u0022Description\u0022:\u0022(UTC-08:00) Pacific Time (US and Canada)\u0022,\u0022Id\u0022:13,\u0022Information\u0022:{\u0022Bias\u0022:480,\u0022DaylightBias\u0022:-60,\u0022StandardBias\u0022:0}},\u0022AdjustHijriDays\u0022:0,\u0022AlternateCalendarType\u0022:0,\u0022AM\u0022:\u0022AM\u0022,\u0022CalendarType\u0022:1,\u0022Collation\u0022:25,\u0022CollationLCID\u0022:2070,\u0022DateFormat\u0022:0,\u0022DateSeparator\u0022:\u0022/\u0022,\u0022DecimalSeparator\u0022:\u0022.\u0022,\u0022DigitGrouping\u0022:\u00223;0\u0022,\u0022FirstDayOfWeek\u0022:0,\u0022FirstWeekOfYear\u0022:0,\u0022IsEastAsia\u0022:false,\u0022IsRightToLeft\u0022:false,\u0022IsUIRightToLeft\u0022:false,\u0022ListSeparator\u0022:\u0022,\u0022,\u0022LocaleId\u0022:1033,\u0022NegativeSign\u0022:\u0022-\u0022,\u0022NegNumberMode\u0022:1,\u0022PM\u0022:\u0022PM\u0022,\u0022PositiveSign\u0022:\u0022\u0022,\u0022ShowWeeks\u0022:false,\u0022ThousandSeparator\u0022:\u0022,\u0022,\u0022Time24\u0022:false,\u0022TimeMarkerPosition\u0022:0,\u0022TimeSeparator\u0022:\u0022:\u0022,\u0022WorkDayEndHour\u0022:1020,\u0022WorkDays\u0022:62,\u0022WorkDayStartHour\u0022:480},\u0022Id\u0022:\u00220299607f-1525-4d06-9f59-76a814d85b0d\u0022,\u0022Url\u0022:\u0022https://ejazhussain.sharepoint.com/sites/pnpcoresdktest\u0022}"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"IsSuccessStatusCode":true,"StatusCode":200,"Headers":{"SPRequestGuid":"3c84f2a1-002f-f000-3a2b-59e8c82c7cd0","SPClientServiceRequestDuration":"11","X-SharePointHealthScore":"3","X-SP-SERVERSTATE":"ReadOnly=0"},"Response":"{\u0022GroupId\u0022:\u002200000000-0000-0000-0000-000000000000\u0022,\u0022Id\u0022:\u0022dc9ac6af-e7e8-4ae3-88e1-e158b99dd3d0\u0022}"}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"IsSuccessStatusCode":false,"StatusCode":404,"Headers":{"SPRequestGuid":"3c84f2a1-e033-f000-6d2c-bacb6b3c2940","SPClientServiceRequestDuration":"31","X-SharePointHealthScore":"0","X-SP-SERVERSTATE":"ReadOnly=0"},"Response":"{\u0022odata.error\u0022:{\u0022code\u0022:\u0022-2147024894, System.IO.FileNotFoundException\u0022,\u0022message\u0022:{\u0022lang\u0022:\u0022en-US\u0022,\u0022value\u0022:\u0022File Not Found.\u0022}}}"}
13 changes: 13 additions & 0 deletions src/sdk/PnP.Core/Model/SharePoint/Core/Internal/Folder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,19 @@ internal static bool ErrorIndicatesFileDoesNotExists(SharePointRestError error)
}
}

internal static bool ErrorIndicatesFolderDoesNotExists(SharePointRestError error)
{
// SharePoint returns ERROR_FILE_NOT_FOUND (-2147024894) for both files and folders
if (error?.HttpResponseCode == 404 && error.ServerErrorCode == -2147024894)
{
return true;
}
else
{
return false;
}
}

#endregion
}
}
38 changes: 36 additions & 2 deletions src/sdk/PnP.Core/Model/SharePoint/Core/Internal/Web.cs
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,24 @@ public async Task<IFolder> GetFolderByServerRelativeUrlAsync(string serverRelati
Parent = this
};

await folder.BaseRetrieveAsync(apiOverride: BuildGetFolderByRelativeUrlApiCall(serverRelativeUrl), fromJsonCasting: folder.MappingHandler, postMappingJson: folder.PostMappingHandler, expressions: expressions).ConfigureAwait(false);
try
{
await folder.BaseRetrieveAsync(apiOverride: BuildGetFolderByRelativeUrlApiCall(serverRelativeUrl), fromJsonCasting: folder.MappingHandler, postMappingJson: folder.PostMappingHandler, expressions: expressions).ConfigureAwait(false);
}
catch (SharePointRestServiceException ex)
{
var error = ex.Error as SharePointRestError;
// SharePoint returns FileNotFoundException for missing folders; normalize to DirectoryNotFoundException
if (Folder.ErrorIndicatesFolderDoesNotExists(error))
{
error.Code = "System.IO.DirectoryNotFoundException";
if (error.Message == "File Not Found.")
{
error.Message = "Folder not found.";
}
}
throw;
}

return folder;
}
Expand Down Expand Up @@ -464,7 +481,24 @@ public async Task<IFolder> GetFolderByIdAsync(Guid folderId, params Expression<F
Parent = this
};

await folder.BaseRetrieveAsync(apiOverride: BuildGetFolderByIdApiCall(folderId), fromJsonCasting: folder.MappingHandler, postMappingJson: folder.PostMappingHandler, expressions: expressions).ConfigureAwait(false);
try
{
await folder.BaseRetrieveAsync(apiOverride: BuildGetFolderByIdApiCall(folderId), fromJsonCasting: folder.MappingHandler, postMappingJson: folder.PostMappingHandler, expressions: expressions).ConfigureAwait(false);
}
catch (SharePointRestServiceException ex)
{
var error = ex.Error as SharePointRestError;
// SharePoint returns FileNotFoundException for missing folders; normalize to DirectoryNotFoundException
if (Folder.ErrorIndicatesFolderDoesNotExists(error))
{
error.Code = "System.IO.DirectoryNotFoundException";
if (error.Message == "File Not Found.")
{
error.Message = "Folder not found.";
}
}
throw;
}

return folder;
}
Expand Down
Loading