Skip to content

Commit ad7efbd

Browse files
Updated how Graph service exceptions are handling in controls (#142)
* Improved Graph exception handling in PeoplePicker and PersonView
1 parent 28e919f commit ad7efbd

File tree

4 files changed

+145
-69
lines changed

4 files changed

+145
-69
lines changed

CommunityToolkit.Graph.Uwp/Controls/LoginButton/LoginButton.cs

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Threading.Tasks;
88
using CommunityToolkit.Authentication;
99
using CommunityToolkit.Graph.Extensions;
10+
using Microsoft.Graph;
1011
using Windows.UI.Xaml;
1112
using Windows.UI.Xaml.Controls;
1213
using Windows.UI.Xaml.Controls.Primitives;
@@ -212,7 +213,13 @@ private async void OnProviderStateChanged(object sender, ProviderStateChangedEve
212213
{
213214
case ProviderState.SignedIn:
214215
IsLoading = true;
215-
await SetUserDetails();
216+
if (!await TrySetUserDetailsAsync())
217+
{
218+
// Failed to retrieve user details, force signout.
219+
await SignOutAsync();
220+
return;
221+
}
222+
216223
IsLoading = false;
217224
LoginCompleted?.Invoke(this, new EventArgs());
218225
break;
@@ -284,20 +291,36 @@ private async void LoadData()
284291
}
285292
}
286293

287-
private async Task SetUserDetails()
294+
private async Task<bool> TrySetUserDetailsAsync()
288295
{
296+
User userDetails = null;
297+
289298
var provider = ProviderManager.Instance.GlobalProvider;
290299
if (provider != null)
291300
{
292301
try
293302
{
294-
UserDetails = await provider.GetClient().GetMeAsync();
303+
userDetails = await provider.GetClient().GetMeAsync();
295304
}
296-
catch
305+
catch (Microsoft.Graph.ServiceException e)
297306
{
298-
// TODO: Handle if UserDetails is null.
307+
if (e.StatusCode == System.Net.HttpStatusCode.Forbidden)
308+
{
309+
// Insufficient privileges.
310+
// Incremental consent must not be supported by the current provider.
311+
// TODO: Log or handle the lack of sufficient privileges.
312+
}
313+
else
314+
{
315+
// Something unexpected happened.
316+
throw;
317+
}
299318
}
300319
}
320+
321+
UserDetails = userDetails;
322+
323+
return UserDetails != null;
301324
}
302325

303326
private void ClearUserDetails()

CommunityToolkit.Graph.Uwp/Controls/PeoplePicker/PeoplePicker.cs

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,25 @@ private async Task UpdateResultsAsync(string text)
105105
IGraphServiceUsersCollectionPage usersCollection = null;
106106
try
107107
{
108+
// Returns an empty collection if no results found.
108109
usersCollection = await graph.FindUserAsync(text);
109110
}
110-
catch
111+
catch (Microsoft.Graph.ServiceException e)
111112
{
112-
// No users found.
113+
if (e.StatusCode == System.Net.HttpStatusCode.Forbidden)
114+
{
115+
// Insufficient privileges.
116+
// Incremental consent must not be supported by the current provider.
117+
// TODO: Log or handle the lack of sufficient privileges.
118+
}
119+
else
120+
{
121+
// Something unexpected happened.
122+
throw;
123+
}
113124
}
114125

115-
if (usersCollection != null)
126+
if (usersCollection != null && usersCollection.Count > 0)
116127
{
117128
foreach (var user in usersCollection.CurrentPage)
118129
{
@@ -127,14 +138,25 @@ private async Task UpdateResultsAsync(string text)
127138
IUserPeopleCollectionPage peopleCollection = null;
128139
try
129140
{
141+
// Returns an empty collection if no results found.
130142
peopleCollection = await graph.FindPersonAsync(text);
131143
}
132-
catch
144+
catch (Microsoft.Graph.ServiceException e)
133145
{
134-
// No people found.
146+
if (e.StatusCode == System.Net.HttpStatusCode.Forbidden)
147+
{
148+
// Insufficient privileges.
149+
// Incremental consent must not be supported by the current provider.
150+
// TODO: Log or handle the lack of sufficient privileges.
151+
}
152+
else
153+
{
154+
// Something unexpected happened.
155+
throw;
156+
}
135157
}
136158

137-
if (peopleCollection != null)
159+
if (peopleCollection != null && peopleCollection.Count > 0)
138160
{
139161
// Grab ids of current suggestions
140162
var ids = list.Cast<object>().Select(person => (person as Person).Id);
@@ -152,4 +174,4 @@ private async Task UpdateResultsAsync(string text)
152174
}
153175
}
154176
}
155-
}
177+
}

CommunityToolkit.Graph.Uwp/Controls/PersonView/PersonView.cs

Lines changed: 81 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,11 @@ private async void LoadData()
121121

122122
if (provider?.State == ProviderState.SignedIn)
123123
{
124-
await TryLoadPersonDetailsAsync();
124+
if (!await TryLoadPersonDetailsAsync())
125+
{
126+
// TODO: Handle failure to load the PersonDetails.
127+
}
128+
125129
UpdateVisual();
126130
}
127131
else
@@ -132,6 +136,12 @@ private async void LoadData()
132136

133137
private async void UpdateVisual()
134138
{
139+
if (PersonDetails == null)
140+
{
141+
LoadDefaultImage();
142+
return;
143+
}
144+
135145
if (PersonAvatarType is PersonAvatarType.Initials)
136146
{
137147
var initialsLoaded = TryLoadInitials();
@@ -144,31 +154,24 @@ private async void UpdateVisual()
144154
LoadDefaultImage();
145155
}
146156
}
147-
else if (PersonDetails != null)
157+
else if (PersonDetails.Id != _photoId)
148158
{
149-
if (PersonDetails.Id != _photoId)
159+
var photoLoaded = await TryLoadUserPhotoAsync();
160+
if (photoLoaded)
150161
{
151-
LoadDefaultImage();
162+
UpdateImageSize();
163+
}
164+
else
165+
{
166+
ClearUserPhoto();
152167

153-
var photoLoaded = await TryLoadUserPhotoAsync();
154-
if (photoLoaded)
155-
{
156-
UpdateImageSize();
157-
}
158-
else
168+
var initialsLoaded = TryLoadInitials();
169+
if (!initialsLoaded)
159170
{
160-
var initialsLoaded = TryLoadInitials();
161-
if (initialsLoaded)
162-
{
163-
ClearUserPhoto();
164-
}
171+
LoadDefaultImage();
165172
}
166173
}
167174
}
168-
else
169-
{
170-
LoadDefaultImage();
171-
}
172175
}
173176

174177
private void LoadDefaultImage()
@@ -200,6 +203,7 @@ private void ClearUserPhoto()
200203

201204
private async Task<bool> TryLoadPersonDetailsAsync()
202205
{
206+
// TODO: Better guarding.
203207
if (PersonDetails != null)
204208
{
205209
return true;
@@ -208,50 +212,61 @@ private async Task<bool> TryLoadPersonDetailsAsync()
208212
var provider = ProviderManager.Instance.GlobalProvider;
209213
if (provider?.State != ProviderState.SignedIn)
210214
{
215+
PersonDetails = null;
211216
return false;
212217
}
213218

219+
var graph = provider.GetClient();
220+
214221
try
215222
{
216223
if (!string.IsNullOrWhiteSpace(UserId))
217224
{
218-
var user = await provider.GetClient().GetUserAsync(UserId);
225+
var user = await graph.GetUserAsync(UserId);
219226
PersonDetails = user.ToPerson();
220227
}
221228
else if (PersonQuery?.ToLowerInvariant() == PersonQueryMe)
222229
{
223-
var user = await provider.GetClient().GetMeAsync();
230+
var user = await graph.GetMeAsync();
224231
PersonDetails = user.ToPerson();
225232
}
226233
else if (!string.IsNullOrWhiteSpace(PersonQuery))
227234
{
228-
var people = await provider.GetClient().FindPersonAsync(PersonQuery);
235+
var people = await graph.FindPersonAsync(PersonQuery);
229236
if (people != null && people.Count > 0)
230237
{
231-
var person = people.FirstOrDefault();
232-
PersonDetails = person;
238+
PersonDetails = people.FirstOrDefault();
233239
}
234240
}
235-
236-
return PersonDetails != null;
237241
}
238-
catch
242+
catch (Microsoft.Graph.ServiceException e)
239243
{
240-
// TODO: Log exception
244+
if (e.StatusCode == System.Net.HttpStatusCode.Forbidden)
245+
{
246+
// Insufficient privileges.
247+
// Incremental consent must not be supported by the current provider.
248+
// TODO: Log or handle the lack of sufficient privileges.
249+
}
250+
else
251+
{
252+
// Something unexpected happened.
253+
throw;
254+
}
241255
}
242256

243-
return false;
257+
return PersonDetails != null;
244258
}
245259

246260
private async Task<bool> TryLoadUserPhotoAsync()
247261
{
262+
// TODO: Better guarding.
248263
var person = PersonDetails;
249264
if (person == null)
250265
{
251266
return false;
252267
}
253268

254-
if (PersonDetails.Id == _photoId && UserPhoto != null && UserPhoto != _defaultImage)
269+
if (person.Id == _photoId && UserPhoto != null && UserPhoto != _defaultImage)
255270
{
256271
return true;
257272
}
@@ -264,27 +279,51 @@ private async Task<bool> TryLoadUserPhotoAsync()
264279

265280
Stream photoStream = null;
266281

267-
// TODO: Better guarding
268282
try
269283
{
270284
var graph = ProviderManager.Instance.GlobalProvider?.GetBetaClient();
271285
photoStream = await graph.GetUserPhoto(person.Id);
272286
}
273-
catch
287+
catch (Microsoft.Graph.ServiceException e)
274288
{
275-
// TODO: Log exception
289+
if (e.StatusCode == System.Net.HttpStatusCode.Forbidden)
290+
{
291+
// Insufficient privileges.
292+
// Incremental consent must not be supported by the current provider.
293+
// TODO: Log or handle the lack of sufficient privileges.
294+
}
295+
else if (e.StatusCode == System.Net.HttpStatusCode.BadRequest)
296+
{
297+
// This entity does not support profile photos.
298+
}
299+
else if (e.StatusCode == System.Net.HttpStatusCode.NotFound)
300+
{
301+
// Image not found.
302+
}
303+
else if ((int)e.StatusCode == 422)
304+
{
305+
// IncorrectRecipientTypeDetected:
306+
// Incorrect recipient type detected in request url. Retry with Groups as the object type.
307+
}
308+
else
309+
{
310+
// Something unexpected happened.
311+
throw;
312+
}
276313
}
277314

278-
if (photoStream != null)
315+
if (photoStream == null)
279316
{
280-
var decodeResults = await TryDecodeStreamAsync(photoStream);
281-
if (decodeResults.Success)
282-
{
283-
UserPhoto = decodeResults.Image;
284-
_photoId = person.Id;
317+
return false;
318+
}
285319

286-
return true;
287-
}
320+
var decodeResults = await TryDecodeStreamAsync(photoStream);
321+
if (decodeResults.Success)
322+
{
323+
UserPhoto = decodeResults.Image;
324+
_photoId = person.Id;
325+
326+
return true;
288327
}
289328

290329
return false;
@@ -341,4 +380,4 @@ private bool TryLoadInitials()
341380
return (false, null);
342381
}
343382
}
344-
}
383+
}

CommunityToolkit.Graph/Extensions/GraphExtensions.People.cs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,13 @@ public static partial class GraphExtensions
2020
/// <returns><see cref="IUserPeopleCollectionPage"/> collection of <see cref="Person"/>.</returns>
2121
public static async Task<IUserPeopleCollectionPage> FindPersonAsync(this GraphServiceClient graph, string query)
2222
{
23-
try
24-
{
25-
return await graph
26-
.Me
27-
.People
28-
.Request()
29-
.Search(query)
30-
////.WithScopes(new string[] { "people.read" })
31-
.GetAsync();
32-
}
33-
catch
34-
{
35-
}
36-
37-
return new UserPeopleCollectionPage();
23+
return await graph
24+
.Me
25+
.People
26+
.Request()
27+
.Search(query)
28+
.WithScopes(new string[] { "people.read" })
29+
.GetAsync();
3830
}
3931
}
4032
}

0 commit comments

Comments
 (0)