Если функция ожидает возвращаемое значение, но внутри функции я улавливаю ошибку и хочу вырваться

#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 в вашем методе здесь.