#c#
#c#
Вопрос:
Если функция ожидает возвращаемое значение, но внутри функции я улавливаю ошибку и хочу выйти из этой функции, как мне это сделать на C # … Моя проблема заключается в следующем (не стесняйтесь переходить к комментируемым строкам):
public static async Task<string> GetData(string url, string props = "")
{
string query = url "?oauth_token=" Contract.access_token props;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(APIURL query);
request.Headers[HttpRequestHeader.IfModifiedSince] = DateTime.Now.ToString();
request.Method = HttpMethod.Get;
try
{
HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();
Debug.WriteLine(response.ContentType);
System.IO.Stream responseStream = response.GetResponseStream();
string data;
using (var reader = new System.IO.StreamReader(responseStream))
{
data = reader.ReadToEnd();
}
responseStream.Close();
APIError error = new APIError ();
try
{
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(APIError ));
error = (APIError )serializer.ReadObject(stream);
}
MessageBox.Show(error.error_description);
return null; // I WANT TO BREAK OUT HERE, I really don't want the application to continue its thread... Is there a way of doing this without having to go and code all my controller model calls to try and catch?
}
catch (Exception e)
{
return data; // The api did not return an error so continue as normal
}
}
catch (Exception ex)
{
var we = ex.InnerException as WebException;
if (we != null)
{
var resp = we.Response as HttpWebResponse;
var code = resp.StatusCode;
MessageBox.Show("RespCallback Exception raised! Message:{0}" we.Message);
Debug.WriteLine("Status:{0}", we.Status);
return we.Message;
}
else
throw;
}
}
Комментарии:
1. IMO, вы помещаете свою обработку исключений в неправильное место. Если вы хотите прервать выполнение, вам следует разрешить всплывающее исключение (или обернуть его в новое) и обработать его на верхнем уровне, где на самом деле имеет смысл отправлять сообщения пользователю и / или записывать в журнал.
2. Итак, что именно вы хотите, чтобы функция делала в случае ошибки (что вы подразумеваете под выходом из функции )? Есть только два варианта: вернуть значение или выдать исключение.
3. Я имею в виду, что, если streamreader успешно создает объект ApiError, затем отправляет пользователю сообщение с отображением ошибки api … затем направляет его на страницу входа. (ошибки будут выдаваться только в том случае, если пользователь достиг своего предела использования api …)
4. ОК. Вы хотите, чтобы все это (отображение ошибки и перенаправление на страницу входа) обрабатывалось в этой функции?
5. В значительной степени getData — это то, куда направляются все вызовы API, и поскольку я вызываю это getData из своего приложения, я не хочу пытаться перехватывать каждый вызов… скорее попробуйте и поймайте здесь … так что, если это действительно возвращаемая ошибка, она отменяет все текущие задачи и просто перенаправляет на мою страницу входа.
Ответ №1:
Не перехватывайте исключение.
Оставьте исключение для перехвата вызывающей стороной — или, при необходимости, перехватите его и оберните в свой собственный Exception
тип.
Вы кладете все свои яйца в одну корзину здесь — ловя его так далеко вниз, вы оставляете вам мало места для маневра. Позволяя ему всплывать, вы получаете больше возможностей для его обработки.
Комментарии:
1. Я действительно хочу это сделать, но это означает, что в моем приложении мне придется изменять каждый вызывающий репозиторий бит кода, чтобы перехватить ошибку… Хотя, я думаю, я могу потратить несколько часов на просмотр контроллеров, если нет другого варианта
2. Это полностью зависит от того, что вы хотите с этим сделать. Если вы просто хотите зарегистрировать это .. затем подключите
AppDomain.UnhandledException
событие и зарегистрируйте его. Если вам нужно выполнить определенную задачу — возможно, вы все еще можете выполнить это в глобальном событии «произошла ошибка». Это может привести к беспорядку, но это вариант (учитывая, что я на самом деле не знаю вашего варианта использования).3. К сожалению, я пока поместил его в UnhandledException .. Я могу пойти и попытаться поймать вызывающих, когда у меня будет больше времени, пока все должно быть в порядке. Спасибо, чувак
4. Нет проблем. Ваш другой вариант — это своего рода Fascade, который выполняет вызов и перехват исключения. Тогда все ваши вызывающие абоненты вызывают один Fascade, и он обрабатывает исключение для них. Идея здесь в том, что это устраняет необходимость обрабатывать это в ядре вашего кода и делегирует его чему-то еще выше.
Ответ №2:
Поместите throw() в конец вашего оператора catch() . Затем он обработает это, но снова выдаст то же исключение, чтобы всплыть.
Ответ №3:
Ваш вызывающий код должен обрабатывать исключения. Если ваше выполнение не может быть продолжено, позвольте всплывающему исключению и удалите некоторые ненужные try / catch в вашем методе здесь.