better error checking for no internet connection on http requests

This commit is contained in:
Austin Diviness 2016-04-15 13:54:11 -07:00
Родитель aaf2bef93c
Коммит 9e181a7d7e
9 изменённых файлов: 160 добавлений и 170 удалений

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

@ -42,49 +42,40 @@ FBSingleValue::FBSingleValue(
Windows::Foundation::IAsyncOperation<FBResult^>^ FBSingleValue::GetAsync(
)
{
return create_async([this]() -> task<FBResult^>
{
FBSession^ sess = FBSession::ActiveSession;
return create_task(FBClient::GetTaskAsync(_request, _parameters))
.then([this](String^ responseString) -> FBResult^
{
return ConsumeSingleValue(responseString);
});
});
return MakeHttpRequest(&FBClient::GetTaskAsync);
}
Windows::Foundation::IAsyncOperation<FBResult^>^ FBSingleValue::PostAsync(
)
{
return create_async([this]() -> task<FBResult^>
{
FBSession^ sess = FBSession::ActiveSession;
return create_task(FBClient::PostTaskAsync(_request, _parameters))
.then([this](String^ responseString) -> FBResult^
{
return ConsumeSingleValue(responseString);
});
});
return MakeHttpRequest(&FBClient::PostTaskAsync);
}
Windows::Foundation::IAsyncOperation<FBResult^>^ FBSingleValue::DeleteAsync(
)
{
return create_async([this]() -> task<FBResult^>
{
FBSession^ sess = FBSession::ActiveSession;
return MakeHttpRequest(&FBClient::DeleteTaskAsync);
}
return create_task(FBClient::DeleteTaskAsync(_request, _parameters))
Windows::Foundation::IAsyncOperation<FBResult^>^ FBSingleValue::MakeHttpRequest(FBClientFunc func)
{
return create_async([this, func]() -> task<FBResult^>
{
return create_task(func(_request, _parameters))
.then([this](String^ responseString) -> FBResult^
{
return ConsumeSingleValue(responseString);
if (responseString == nullptr)
{
return ref new FBResult(ref new FBError(0, L"HTTP request failed", "unable to receive response"));
}
else
{
return ConsumeSingleValue(responseString);
}
});
});
}
FBResult^ FBSingleValue::ConsumeSingleValue(
String^ JsonText
)

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

@ -20,6 +20,10 @@
#include "FacebookClient.h"
#include "FacebookResult.h"
typedef Windows::Foundation::IAsyncOperation<Platform::String^>^
(*FBClientFunc)
(Platform::String^ path, Windows::Foundation::Collections::PropertySet^ parameters);
namespace winsdkfb
{
namespace Graph
@ -78,6 +82,10 @@ namespace winsdkfb
Platform::String^ JsonText
);
Windows::Foundation::IAsyncOperation<FBResult^>^ FBSingleValue::MakeHttpRequest(
FBClientFunc func
);
FBResult^ _result;
Platform::String^ _request;
Windows::Foundation::Collections::PropertySet^ _parameters;

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

@ -192,31 +192,8 @@ task<String^> FBClient::GetTaskInternalAsync(
cancellation_token_source();
filter->CacheControl->ReadBehavior = HttpCacheReadBehavior::Default;
return create_task(httpClient->GetAsync(RequestUri),
cancellationTokenSource.get_token())
.then([=](HttpResponseMessage^ response)
{
return create_task(response->Content->ReadAsStringAsync(),
cancellationTokenSource.get_token());
})
.then([=](task<String^> resultTask)
{
String^ result = nullptr;
try
{
result = resultTask.get();
}
catch (const task_canceled&)
{
}
catch (Exception^ ex)
{
throw ex;
}
return result;
});
task<HttpResponseMessage^> httpRequestTask = create_task(httpClient->GetAsync(RequestUri), cancellationTokenSource.get_token());
return TryReceiveHttpResponse(httpRequestTask, cancellationTokenSource);
}
PropertySet^ FBClient::GetStreamsToUpload(
@ -295,32 +272,8 @@ task<String^> FBClient::SimplePostInternalAsync(
cancellation_token_source cancellationTokenSource =
cancellation_token_source();
return create_task(
httpClient->PostAsync(RequestUri, ref new HttpStringContent(L"")),
cancellationTokenSource.get_token())
.then([=](HttpResponseMessage^ response)
{
return create_task(response->Content->ReadAsStringAsync(),
cancellationTokenSource.get_token());
})
.then([=](task<String^> previousTask)
{
String^ response = nullptr;
try
{
// Check if any previous task threw an exception.
response = previousTask.get();
}
catch (const task_canceled&)
{
}
catch (Exception^ ex)
{
}
return response;
});
task<HttpResponseMessage^> httpRequestTask = create_task(httpClient->PostAsync(RequestUri, ref new HttpStringContent(L"")), cancellationTokenSource.get_token());
return TryReceiveHttpResponse(httpRequestTask, cancellationTokenSource);
}
void FBClient::AddStreamsToForm(
@ -400,36 +353,11 @@ task<String^> FBClient::MultipartPostInternalAsync(
ref new HttpMultipartFormDataContent();
cancellation_token_source cancellationTokenSource =
cancellation_token_source();
HttpResponseMessage^ msg = nullptr;
String^ response = L"";
FBClient::AddStreamsToForm(Streams, form);
return create_task(httpClient->PostAsync(RequestUri, form),
cancellationTokenSource.get_token())
.then([=](HttpResponseMessage^ response) -> task<String^>
{
return create_task(response->Content->ReadAsStringAsync(),
cancellationTokenSource.get_token());
})
.then([=](task<String^> previousTask) -> String^
{
String^ response = nullptr;
try
{
// Check if any previous task threw an exception.
response = previousTask.get();
}
catch (const task_canceled&)
{
}
catch (Exception^ ex)
{
}
return response;
});
task<HttpResponseMessage^> httpRequestTask = create_task(httpClient->PostAsync(RequestUri, form), cancellationTokenSource.get_token());
return TryReceiveHttpResponse(httpRequestTask, cancellationTokenSource);
}
IAsyncOperation<String^>^ FBClient::PostTaskAsync(
@ -501,32 +429,8 @@ task<String^> FBClient::DeleteTaskInternalAsync(
cancellation_token_source cancellationTokenSource =
cancellation_token_source();
return create_task(
httpClient->DeleteAsync(RequestUri),
cancellationTokenSource.get_token())
.then([=](HttpResponseMessage^ response)
{
return create_task(response->Content->ReadAsStringAsync(),
cancellationTokenSource.get_token());
})
.then([=](task<String^> previousTask)
{
String^ response = nullptr;
try
{
// Check if any previous task threw an exception.
response = previousTask.get();
}
catch (const task_canceled&)
{
}
catch (Exception^ ex)
{
}
return response;
});
task<HttpResponseMessage^> httpRequestTask = create_task(httpClient->DeleteAsync(RequestUri), cancellationTokenSource.get_token());
return TryReceiveHttpResponse(httpRequestTask, cancellationTokenSource);
}
Uri^ FBClient::PrepareRequestUri(
@ -855,3 +759,47 @@ BOOL FBClient::IsOAuthErrorResponse(
return (err && err->Code == 190);
}
task<String^> FBClient::TryReceiveHttpResponse(
task<HttpResponseMessage^> httpRequestTask,
cancellation_token_source cancellationTokenSource
)
{
task<String^> getHttpTask = create_task([=]()
{
task<String^> resultTask = create_task([]() -> String^ {return nullptr; });
try
{
HttpResponseMessage^ responseMessage = httpRequestTask.get();
if (responseMessage && responseMessage->IsSuccessStatusCode)
{
resultTask = create_task(responseMessage->Content->ReadAsStringAsync(), cancellationTokenSource.get_token());
}
}
catch (COMException^ e)
{
OutputDebugString(e->ToString()->Data());
}
catch (const task_canceled&)
{
OutputDebugString(L"http request task canceled");
}
return resultTask;
});
return create_task([=]()
{
String^ result = nullptr;
try
{
result = getHttpTask.get();
}
catch (COMException^ e)
{
OutputDebugString(e->ToString()->Data());
}
catch (const task_canceled&)
{
OutputDebugString(L"http request task canceled");
}
return result;
});
}

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

@ -134,5 +134,10 @@ namespace winsdkfb
Windows::Foundation::Uri^ RequestUri,
Windows::Foundation::Collections::PropertySet^ Streams
);
static concurrency::task<Platform::String^> TryReceiveHttpResponse(
concurrency::task<Windows::Web::Http::HttpResponseMessage^> httpRequestTask,
concurrency::cancellation_token_source cancellationTokenSource
);
};
};

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

@ -30,7 +30,24 @@ FBError::FBError(
_code(0),
_subcode(0),
_errorUserTitle(nullptr),
_errorUserMessage(nullptr)
_errorUserMessage(nullptr),
_exception(nullptr)
{
;
}
FBError::FBError(
int Code,
String^ Type,
String^ Message
) :
_code(Code),
_errorUserMessage(nullptr),
_errorUserTitle(nullptr),
_message(Message),
_subcode(0),
_type(Type),
_exception(nullptr)
{
;
}
@ -65,6 +82,10 @@ String^ FBError::ErrorUserMessage::get()
return _errorUserMessage;
}
Exception^ FBError::Exception::get()
{
return _exception;
}
FBError^ FBError::FromUri(
Uri^ ResponseUri
@ -195,17 +216,13 @@ FBError^ FBError::FromJson(
return result;
}
FBError::FBError(
int Code,
String^ Type,
String^ Message
) :
_code(Code),
_errorUserMessage(nullptr),
_errorUserTitle(nullptr),
_message(Message),
_subcode(0),
_type(Type)
FBError^ FBError::FromException(
Platform::Exception^ e
)
{
;
}
FBError^ result = ref new FBError();
result->_exception = e;
result->_type = L"An exception occurred";
result->_message = e->ToString();
return result;
}

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

@ -69,6 +69,10 @@ namespace winsdkfb
Platform::String^ JsonText
);
static FBError^ FromException(
Platform::Exception^ e
);
FBError(
int Code,
Platform::String^ Type,
@ -111,6 +115,11 @@ namespace winsdkfb
Platform::String^ get();
}
property Platform::Exception^ Exception
{
Platform::Exception^ get();
}
private:
FBError(
);
@ -121,5 +130,6 @@ namespace winsdkfb
int _subcode;
Platform::String^ _errorUserTitle;
Platform::String^ _errorUserMessage;
Platform::Exception^ _exception;
};
}

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

@ -46,14 +46,7 @@ FBPaginatedArray::FBPaginatedArray(
Windows::Foundation::IAsyncOperation<FBResult^>^ FBPaginatedArray::FirstAsync(
)
{
return create_async([this]() -> task<FBResult^>
{
return create_task(FBClient::GetTaskAsync(_request, _parameters))
.then([this](String^ responseString)
{
return ConsumePagedResponse(responseString);
});
});
return GetPage(_request);
}
Windows::Foundation::IAsyncOperation<FBResult^>^ FBPaginatedArray::NextAsync(
@ -61,16 +54,12 @@ Windows::Foundation::IAsyncOperation<FBResult^>^ FBPaginatedArray::NextAsync(
{
if (!HasNext)
{
throw ref new InvalidArgumentException(SDKMessageBadCall);
}
return create_async([this]() -> task<FBResult^>
{
return create_task(FBClient::GetTaskAsync(_paging->Next, _parameters))
.then([this](String^ responseString)
return create_async([this]()
{
return ConsumePagedResponse(responseString);
return ref new FBResult(FBError::FromException(ref new InvalidArgumentException(SDKMessageBadCall)));
});
});
}
return GetPage(_paging->Next);
}
Windows::Foundation::IAsyncOperation<FBResult^>^ FBPaginatedArray::PreviousAsync(
@ -78,16 +67,12 @@ Windows::Foundation::IAsyncOperation<FBResult^>^ FBPaginatedArray::PreviousAsync
{
if (!HasPrevious)
{
throw ref new InvalidArgumentException(SDKMessageBadCall);
}
return create_async([this]() -> task<FBResult^>
{
return create_task(FBClient::GetTaskAsync(_paging->Previous, _parameters))
.then([this](String^ responseString)
return create_async([this]()
{
return ConsumePagedResponse(responseString);
return ref new FBResult(FBError::FromException(ref new InvalidArgumentException(SDKMessageBadCall)));
});
});
}
return GetPage(_paging->Previous);
}
IVectorView<Object^>^ FBPaginatedArray::Current::get()
@ -237,3 +222,24 @@ IVectorView<Object^>^ FBPaginatedArray::ObjectArrayFromWebResponse(
return result;
}
Windows::Foundation::IAsyncOperation<FBResult^>^ FBPaginatedArray::GetPage(
String^ path
)
{
return create_async([this, path]() -> task<FBResult^>
{
return create_task(FBClient::GetTaskAsync(path, _parameters))
.then([this](String^ responseString)
{
if (responseString == nullptr)
{
return ref new FBResult(ref new FBError(0, L"HTTP request failed", "unable to receive response"));
}
else
{
return ConsumePagedResponse(responseString);
}
});
});
}

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

@ -147,6 +147,11 @@ namespace winsdkfb
Platform::String^ JsonText
);
Windows::Foundation::IAsyncOperation<FBResult^>^ GetPage(
Platform::String^ path
);
Windows::Foundation::Collections::IVectorView<Object^>^ _current;
FBPaging^ _paging;
Platform::String^ _request;

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

@ -49,7 +49,7 @@ using namespace Windows::UI::Xaml::Media::Imaging;
#define ProfilePictureSillhouetteImage \
"ms-appx:///Facebook/Images/fb_blank_profile_portrait.png"
"ms-appx:///winsdkfb/Images/fb_blank_profile_portrait.png"
// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236
@ -197,7 +197,7 @@ ProfilePictureControl::GetProfilePictureInfo(
}
else
{
String^ path = L"/" + UserId + L"/picture";
String^ path = UserId + L"/picture";
FBSingleValue^ value = ref new FBSingleValue(
path,