Пользовательские исключения и диалог сообщений в предложении Try-Catch
Я разрабатываю универсальное приложение, которому нужно несколько пользовательских исключений для обнаружения ошибок, возникающих при вызове веб-сервисов: NoInternetAccessException, NoJSONException, UserTimeoutException, ...
Вот пример одного из этих классов:
public class NoInternetAccessException : Exception
{
private DateTime time;
public DateTime Time { get { return time; } }
public NoInternetAccessException(string message, DateTime time)
: base(message)
{
this.time = time;
}
}
Я ловлю эти исключения в нескольких местах:
в JSONParser, где я создаю URI и вызываю метод Client.GetAsync:
...
try
{
CancellationTokenSource cts = new CancellationTokenSource(Timeout);
response = await client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead).AsTask(cts.Token);
if (response.IsSuccessStatusCode)
return response;
}
catch (TaskCanceledException)
{
if ((_currentRetries == MaxRetries)
throw new UserTimeoutException("User Timeout Exception", DateTime.Now);
else
_currentRetries++;
}
catch (Exception e)
{
if (e.HResult == -2147012889)
throw new WrongUrlException("Wrong URL Exception", e, DateTime.Now);
}
...
в помощнике WebService, где я управляю всеми вызовами веб-сервисов:
public static async Task<Infos> GetInfos(String url, List<KeyValuePair<String, String>> parameters, String protocol)
{
var response = await JSONParser.getJSONFromUrl(url, parameters, "");
Infos infos = new Infos();
try
{
WsResponse wsResponse = JsonConvert.DeserializeObject<Infos>(response.ToString());
infosCe = JsonConvert.DeserializeObject<Infos>(wsResponse.data.ToString());
return infosCe;
}
catch (Exception e)
{
throw new DeserializeException("Deserialize exception", e, DateTime.Now, "Infos");
}
}
Все эти исключения в конечном итоге перехватываются моделями представления после вызова веб-служб:
private async Task<Infos> WebServiceGetInfos()
{
...
try
{
Infos infos = await WebServices.GetInfos(url, parameters, "");
return infosCe;
}
// Exceptions
catch (DeserializeException dE)
{
ExceptionsMsgboxHelper.MsgboxDeserialize(dE);
return null;
}
catch (NoInternetAccessException niaE)
{
ExceptionsMsgboxHelper.MsgboxNoInternetAccess(niaE, true, "");
return null;
}
catch (NoJSONException njsonE)
{
ExceptionsMsgboxHelper.MsgboxNoJSON(njsonE);
return null;
}
...
}
Я хотел бы, чтобы каждое исключение вызывало помощник ExceptionsMsgboxHelper, который показывает определенный диалог сообщений для каждого исключения:
public async static void MsgboxNoJSON(NoJSONException njsonE)
{
Windows.UI.Popups.MessageDialog msgbox =
new Windows.UI.Popups.MessageDialog("There is a problem when retrieving data. If the problem persists, please contact your administrator.",
"Unexpected data received");
await msgbox.ShowAsync();
}
=> Но это не работает, так как диалог сообщений не работает в предложении Try-Catch...
Я также ищу решение для stackru:
Диалог сообщения не отображается в предложении catch
Try-Catch не показывает диалоговое окно сообщения с ожиданием
Но я не вижу, как адаптировать это решение к моему случаю, так как я использую несколько пользовательских исключений:
public static async Task Foo()
{
Exception e = null;
try
{
//just something to throw an exception
int a = 0;
int n = 1 / a;
}
catch (Exception ex)
{
e = ex;
}
if (e != null)
await ShowDialog();
}
=> Это лучший способ сделать это, чем дублировать этот код для каждого пользовательского исключения?
...
DeserializeException dEx = null;
NoInternetAccessException niaEx = null;
NoJSONException njsonEx = null;
try
{
Infos infos = await WebServices.GetInfos(url, parameters, "");
return infosCe;
}
// Exceptions
catch (DeserializeException dE)
{
dEx = de;
}
catch (NoInternetAccessException niaE)
{
niaEx = niaE;
}
catch (NoJSONException njsonE)
{
njsonEx=njsonE;
}
...
if (dEx != null)
{
ExceptionsMsgboxHelper.MsgboxDeserialize(dEx);
return null;
}
if (niaEx != null)
{
ExceptionsMsgboxHelper.MsgboxNoInternetAccess(niaEx);
return null;
}
if (njsonEx != null)
{
ExceptionsMsgboxHelper.MsgboxNoJSON(njsonEx);
return null;
}
...
=> Кажется, он не мощный и не обслуживаемый...
1 ответ
Я наконец решил свою проблему, поймав обобщенное исключение и протестировав его:
...
Exception ex = null;
try
{
Infos infos = await WebServices.GetInfos(url, parameters, "");
return infosCe;
}
// Exceptions
catch (Exception e)
{
ex = e;
}
if (ex != null)
{
if (ex is DeserializeException)
{
DeserializeException dE = (DeserializeException)ex;
ExceptionsMsgboxHelper.MsgboxDeserialize(dE);
}
if (ex is NoInternetAccessException)
{
NoInternetAccessException niaE = (NoInternetAccessException)ex;
ExceptionsMsgboxHelper.MsgboxNoInternetAccess(niaE);
}
if (ex is NoJSONException)
{
NoJSONException njsonE = (NoJSONException)ex;
ExceptionsMsgboxHelper.MsgboxNoJSON(njsonE);
}
...
}
return null;
=> Если вы считаете, что есть лучший способ сделать это, пожалуйста, укажите меня.