Updated how Graph service exceptions are handling in controls (#142)

* Improved Graph exception handling in PeoplePicker and PersonView
This commit is contained in:
Shane Weaver 2021-08-06 14:57:07 -07:00 коммит произвёл GitHub
Родитель 28e919f8a5
Коммит ad7efbd785
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 145 добавлений и 69 удалений

Просмотреть файл

@ -7,6 +7,7 @@ using System.ComponentModel;
using System.Threading.Tasks;
using CommunityToolkit.Authentication;
using CommunityToolkit.Graph.Extensions;
using Microsoft.Graph;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
@ -212,7 +213,13 @@ namespace CommunityToolkit.Graph.Uwp.Controls
{
case ProviderState.SignedIn:
IsLoading = true;
await SetUserDetails();
if (!await TrySetUserDetailsAsync())
{
// Failed to retrieve user details, force signout.
await SignOutAsync();
return;
}
IsLoading = false;
LoginCompleted?.Invoke(this, new EventArgs());
break;
@ -284,20 +291,36 @@ namespace CommunityToolkit.Graph.Uwp.Controls
}
}
private async Task SetUserDetails()
private async Task<bool> TrySetUserDetailsAsync()
{
User userDetails = null;
var provider = ProviderManager.Instance.GlobalProvider;
if (provider != null)
{
try
{
UserDetails = await provider.GetClient().GetMeAsync();
userDetails = await provider.GetClient().GetMeAsync();
}
catch
catch (Microsoft.Graph.ServiceException e)
{
// TODO: Handle if UserDetails is null.
if (e.StatusCode == System.Net.HttpStatusCode.Forbidden)
{
// Insufficient privileges.
// Incremental consent must not be supported by the current provider.
// TODO: Log or handle the lack of sufficient privileges.
}
else
{
// Something unexpected happened.
throw;
}
}
}
UserDetails = userDetails;
return UserDetails != null;
}
private void ClearUserDetails()

Просмотреть файл

@ -105,14 +105,25 @@ namespace CommunityToolkit.Graph.Uwp.Controls
IGraphServiceUsersCollectionPage usersCollection = null;
try
{
// Returns an empty collection if no results found.
usersCollection = await graph.FindUserAsync(text);
}
catch
catch (Microsoft.Graph.ServiceException e)
{
// No users found.
if (e.StatusCode == System.Net.HttpStatusCode.Forbidden)
{
// Insufficient privileges.
// Incremental consent must not be supported by the current provider.
// TODO: Log or handle the lack of sufficient privileges.
}
else
{
// Something unexpected happened.
throw;
}
}
if (usersCollection != null)
if (usersCollection != null && usersCollection.Count > 0)
{
foreach (var user in usersCollection.CurrentPage)
{
@ -127,14 +138,25 @@ namespace CommunityToolkit.Graph.Uwp.Controls
IUserPeopleCollectionPage peopleCollection = null;
try
{
// Returns an empty collection if no results found.
peopleCollection = await graph.FindPersonAsync(text);
}
catch
catch (Microsoft.Graph.ServiceException e)
{
// No people found.
if (e.StatusCode == System.Net.HttpStatusCode.Forbidden)
{
// Insufficient privileges.
// Incremental consent must not be supported by the current provider.
// TODO: Log or handle the lack of sufficient privileges.
}
else
{
// Something unexpected happened.
throw;
}
}
if (peopleCollection != null)
if (peopleCollection != null && peopleCollection.Count > 0)
{
// Grab ids of current suggestions
var ids = list.Cast<object>().Select(person => (person as Person).Id);
@ -152,4 +174,4 @@ namespace CommunityToolkit.Graph.Uwp.Controls
}
}
}
}
}

Просмотреть файл

@ -121,7 +121,11 @@ namespace CommunityToolkit.Graph.Uwp.Controls
if (provider?.State == ProviderState.SignedIn)
{
await TryLoadPersonDetailsAsync();
if (!await TryLoadPersonDetailsAsync())
{
// TODO: Handle failure to load the PersonDetails.
}
UpdateVisual();
}
else
@ -132,6 +136,12 @@ namespace CommunityToolkit.Graph.Uwp.Controls
private async void UpdateVisual()
{
if (PersonDetails == null)
{
LoadDefaultImage();
return;
}
if (PersonAvatarType is PersonAvatarType.Initials)
{
var initialsLoaded = TryLoadInitials();
@ -144,31 +154,24 @@ namespace CommunityToolkit.Graph.Uwp.Controls
LoadDefaultImage();
}
}
else if (PersonDetails != null)
else if (PersonDetails.Id != _photoId)
{
if (PersonDetails.Id != _photoId)
var photoLoaded = await TryLoadUserPhotoAsync();
if (photoLoaded)
{
LoadDefaultImage();
UpdateImageSize();
}
else
{
ClearUserPhoto();
var photoLoaded = await TryLoadUserPhotoAsync();
if (photoLoaded)
var initialsLoaded = TryLoadInitials();
if (!initialsLoaded)
{
UpdateImageSize();
}
else
{
var initialsLoaded = TryLoadInitials();
if (initialsLoaded)
{
ClearUserPhoto();
}
LoadDefaultImage();
}
}
}
else
{
LoadDefaultImage();
}
}
private void LoadDefaultImage()
@ -200,6 +203,7 @@ namespace CommunityToolkit.Graph.Uwp.Controls
private async Task<bool> TryLoadPersonDetailsAsync()
{
// TODO: Better guarding.
if (PersonDetails != null)
{
return true;
@ -208,50 +212,61 @@ namespace CommunityToolkit.Graph.Uwp.Controls
var provider = ProviderManager.Instance.GlobalProvider;
if (provider?.State != ProviderState.SignedIn)
{
PersonDetails = null;
return false;
}
var graph = provider.GetClient();
try
{
if (!string.IsNullOrWhiteSpace(UserId))
{
var user = await provider.GetClient().GetUserAsync(UserId);
var user = await graph.GetUserAsync(UserId);
PersonDetails = user.ToPerson();
}
else if (PersonQuery?.ToLowerInvariant() == PersonQueryMe)
{
var user = await provider.GetClient().GetMeAsync();
var user = await graph.GetMeAsync();
PersonDetails = user.ToPerson();
}
else if (!string.IsNullOrWhiteSpace(PersonQuery))
{
var people = await provider.GetClient().FindPersonAsync(PersonQuery);
var people = await graph.FindPersonAsync(PersonQuery);
if (people != null && people.Count > 0)
{
var person = people.FirstOrDefault();
PersonDetails = person;
PersonDetails = people.FirstOrDefault();
}
}
return PersonDetails != null;
}
catch
catch (Microsoft.Graph.ServiceException e)
{
// TODO: Log exception
if (e.StatusCode == System.Net.HttpStatusCode.Forbidden)
{
// Insufficient privileges.
// Incremental consent must not be supported by the current provider.
// TODO: Log or handle the lack of sufficient privileges.
}
else
{
// Something unexpected happened.
throw;
}
}
return false;
return PersonDetails != null;
}
private async Task<bool> TryLoadUserPhotoAsync()
{
// TODO: Better guarding.
var person = PersonDetails;
if (person == null)
{
return false;
}
if (PersonDetails.Id == _photoId && UserPhoto != null && UserPhoto != _defaultImage)
if (person.Id == _photoId && UserPhoto != null && UserPhoto != _defaultImage)
{
return true;
}
@ -264,27 +279,51 @@ namespace CommunityToolkit.Graph.Uwp.Controls
Stream photoStream = null;
// TODO: Better guarding
try
{
var graph = ProviderManager.Instance.GlobalProvider?.GetBetaClient();
photoStream = await graph.GetUserPhoto(person.Id);
}
catch
catch (Microsoft.Graph.ServiceException e)
{
// TODO: Log exception
if (e.StatusCode == System.Net.HttpStatusCode.Forbidden)
{
// Insufficient privileges.
// Incremental consent must not be supported by the current provider.
// TODO: Log or handle the lack of sufficient privileges.
}
else if (e.StatusCode == System.Net.HttpStatusCode.BadRequest)
{
// This entity does not support profile photos.
}
else if (e.StatusCode == System.Net.HttpStatusCode.NotFound)
{
// Image not found.
}
else if ((int)e.StatusCode == 422)
{
// IncorrectRecipientTypeDetected:
// Incorrect recipient type detected in request url. Retry with Groups as the object type.
}
else
{
// Something unexpected happened.
throw;
}
}
if (photoStream != null)
if (photoStream == null)
{
var decodeResults = await TryDecodeStreamAsync(photoStream);
if (decodeResults.Success)
{
UserPhoto = decodeResults.Image;
_photoId = person.Id;
return false;
}
return true;
}
var decodeResults = await TryDecodeStreamAsync(photoStream);
if (decodeResults.Success)
{
UserPhoto = decodeResults.Image;
_photoId = person.Id;
return true;
}
return false;
@ -341,4 +380,4 @@ namespace CommunityToolkit.Graph.Uwp.Controls
return (false, null);
}
}
}
}

Просмотреть файл

@ -20,21 +20,13 @@ namespace CommunityToolkit.Graph.Extensions
/// <returns><see cref="IUserPeopleCollectionPage"/> collection of <see cref="Person"/>.</returns>
public static async Task<IUserPeopleCollectionPage> FindPersonAsync(this GraphServiceClient graph, string query)
{
try
{
return await graph
.Me
.People
.Request()
.Search(query)
////.WithScopes(new string[] { "people.read" })
.GetAsync();
}
catch
{
}
return new UserPeopleCollectionPage();
return await graph
.Me
.People
.Request()
.Search(query)
.WithScopes(new string[] { "people.read" })
.GetAsync();
}
}
}