2012-06-28 13 views
11

Hola estoy usando HttpClient similar a esto:HttpClient - tratar las excepciones agregados

public static Task<string> AsyncStringRequest(string url, string contentType) 
{ 
    try 
    { 
     var client = new HttpClient(); 
     client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(contentType)); 

     return client.GetStringAsync(url).ContinueWith(task => { 
      return task.Result; 
     }); 
    } 
    catch (AggregateException ex) 
    { 
     throw ex; 
    } 
    catch (WebException ex) 
    { 
     throw ex; 
    }  
    catch (Exception ex) 
    { 
     throw ex; 
    } 
} 

pero estoy teniendo dificultades para tratar las excepciones. He agregado los bloques catch adicionales solo para probar y lanzar paso a paso, pero ninguno de los puntos de ruptura queda atrapado en ninguno de los bloques catch. Me doy cuenta de que al utilizar Tarea, la excepción podría ocurrir en un hilo diferente al llamador, por lo que la excepción se envuelve en un contenedor agregado, pero no estoy seguro de cuál es la mejor forma de lidiar con estas excepciones.

Por ejemplo, realizo una solicitud a un servicio web y especifico un parámetro no válido en la solicitud, y se lanza una excepción. Quiero que pueda ver las excepciones agregadas y ver las excepciones internas para determinar por qué la solicitud falló y devolver un mensaje amistoso.

Así que mi pregunta es, ¿cuál es la mejor manera de atrapar estas excepciones globales y lidiar con ellas?

Respuesta

18

La excepción es lanzada por task.Result:

var client = new HttpClient(); 
client.DefaultRequestHeaders.Accept.Add(...); 
return client.GetStringAsync(url).ContinueWith(task => 
{ 
    try 
    { 
     return task.Result; 
    } 
    catch (AggregateException ex) 
    { 
     throw ex; 
    } 
    catch (WebException ex) 
    { 
     throw ex; 
    }  
    catch (Exception ex) 
    { 
     throw ex; 
    } 
}); 

Mejor: comprobar si la tarea faulted antes de acceder task.Result:

var client = new HttpClient(); 
client.DefaultRequestHeaders.Accept.Add(...); 
return client.GetStringAsync(url).ContinueWith(task => 
{ 
    if (task.IsFaulted) 
    { 
     var ex = task.Exception; 
    } 
    else if (task.IsCancelled) 
    { 
    } 
    else 
    { 
     return task.Result; 
    } 
}); 

Si usted no está haciendo algo en el ContinueWith, puede simplemente omítalo:

var client = new HttpClient(); 
client.DefaultRequestHeaders.Accept.Add(...); 
return client.GetStringAsync(url); 
+0

Genial, lo probaré en la próxima hora! – gdp

+9

Sé que esta es una pregunta antigua, pero ¿hay alguna forma de obtener el código de estado http desde la excepción aggregate, como puede hacerlo al capturar una Webexception? – gdp

+0

@gdp: Sí, puede llamar a .Flatten en AggregateException y luego acceder a la propiedad InnerExceptions y extraer la WebException que contiene. –