Cosa è meglio per restituire dal DataService: Stato o Eccezioni?

3

Ho un'app MVVM con DataServices (usando mvvmlight).

In questo momento, lo sto usando come

var answer = await myDataService.PullList(categoryId);
if (answer.Status == Ok)
    ObservableListOfItems.ReplaceWith(answer.Collection); // Show results
if (answer.Status == ConnectionLost)
    // Handle connection lost state, show msg window or something
if (answer.Status == ParsingError)
    // Handle parsing problem

dove

async Task<MyAnswer> PullList(int id)
{
    // Just a wrapper around HttpWebRequest, returns String.Empty if something happened
    var resultString = await NetworkManager.GetAsync(UrlGenerator.GenerateCategoryRequest(id));  

    if (String.IsNullOrEmpty(resultString))
        return new MyAnswer {Status = ConnectionLost);

    try
    {
        var parsedResult = JsonConvert.DeserializeObject<PocoProducts>();

        return new MyAnswer {Status = Ok, Collection = parsedResult.List);
    }
    catch (Exception)
    {
         return new MyAnswer {Status = ParsingError; }
    } 

e

public class MyAnswer()
{
    public List<Items> {get; set;}
    public EnumStatuses Statuc {get; set;}
}

public enum EnumStatuses
{
    Ok = 0,
    ConnectionLost,
    ParsingError
}

Quindi sono curioso, ho appena re-inventato delle eccezioni, vero?

PS: ha scritto un codice proprio qui, gli errori di battitura sono possibili, ma l'idea generale dovrebbe essere chiara

    
posta Vitalii Vasylenko 17.05.2014 - 18:19
fonte

2 risposte

3

Credo che il mio problema principale con questo è

What happens if an exception occurs during parsing. How will you diagnose it or know what has occurred?

Il motivo per cui lo chiedo è che l'eccezione stessa viene ignorata e si sta semplicemente restituendo un new MyAnswer . Non ho necessariamente alcun problema con questo se stai registrando l'eccezione, ma questo non sembra essere il caso qui.

Incluso in questo, stai rilevando un'eccezione generale? DeserializeObject lanciare eccezioni specifiche? Non sono al 100% su questo, ma dove è possibile cogliere l'eccezione più specifica che conosci e lasciare il resto a gonfiarsi. Una ragione per questo è che il tuo codice è più facile da seguire poiché sai esattamente cosa hai a che fare con il metodo e puoi codificarlo di conseguenza.

Quindi in sintesi. In generale mi piace per lo meno fare qualcosa con l'eccezione che sia il rilancio, includendolo nella risposta o registrandolo. Mi piace anche catturare l'eccezione più specifica possibile al punto di interesse per garantire che il codice sia più facile da seguire e, a lungo termine, fornire una soluzione più solida.

    
risposta data 17.05.2014 - 22:42
fonte
1

Ho alcune app che usano codice come il tuo codice. Io uso HttpClient e ho alcuni errori di tipi. Ad esempio MyWebException .

È sufficiente per mantenere l'utente informato. Ad esempio, se il server Web non è disponibile, otterremo response.StatusCode != HttpStatusCode.OK e lanciamo MyWebException . E se otteniamo json ma non possiamo analizzarlo, quindi lancia Exception .

Se otteniamo MyWebException , mostriamo il messaggio "Siamo spiacenti, abbiamo problemi con il server web o segnale non valido" . Se Exception allora "Spiacente, qualcosa di sbagliato" .

Puoi anche specificare l'errore, se necessario.

Ecco come funziona:

API:

 public async static Task<CPParkingZones> GetZones()
        {           
            return await CPRequestService.Get<CPParkingZones>(string.Format("objects?types=zone"));        
        }

RequestService:

public async static Task<T> Get<T>(string url) where T : CPBase, new()
        {
            try
            {                
                using (var httpClient = new HttpClient())
                {
                    var response = await httpClient.GetAsync(CPConfig.APIServer + url);
                    var responseObject = new T();
                    if (response.StatusCode != HttpStatusCode.OK)
                    {
                        responseObject.Error = new MyWebException();
                        return responseObject;
                    }
                    response.EnsureSuccessStatusCode();
                    string jsonResponse = await response.Content.ReadAsStringAsync();
                    responseObject = JsonConvert.DeserializeObject<T>(jsonResponse);
                    responseObject.Status = response.StatusCode;
                    return responseObject;
                }
            }
            catch (Exception ex)
            {
                var responseObject = new T();
                responseObject.Error = ex;
                return responseObject;
            }
        }

Classe base

public class CPBase 
{                    
        public Exception Error { get; set; }
}

con

var zones = await CPMapObjectsAPI.GetZones();

if (zones.Error != null)
{   
    if (zones.Error is WebException)
    {  
       DialogService.ShowMessage("Sorry, we have troubles with web server or bad signal");    
    }  
    else
    {
       DialogService.ShowMessage("Sorry, something wrong");    
    }         
}

Questo è solo un esempio, il design "IF constructs" sembra scomodo, specialmente se hai bisogno di molti tipi di errori, puoi usare molte opzioni per scrivere meglio questo codice.

    
risposta data 19.05.2014 - 20:49
fonte

Leggi altre domande sui tag