Improve exception from SftpClient.BeginDownloadFile
Nessuno ha ancora preso questa issue.
- Lingua principale
- C#
- Stelle
- 4.4k
- Fork
- 993
- Merge medio
- 9g 21h
- PR unite (30g)
- 1
Descrizione
I recently ran into an issue using SftpClient.BeginDownloadFile(). It turned out that the asyncCallback function I was passing was throwing an exception, but it was more difficult than anticipated to find the root cause because the exception from my function was caught by BeginDownloadFile(), which then reacts by calling asyncResult.SetAsCompleted(exp, false), which in turn throws an InvalidOperationException because the completion flag was already set before executing my callback function. (The root cause becomes apparent when breaking on first-chance exceptions but I often have that turned off due to nuisances it can create.)
As I see it, a simple thing to do to improve this would be to modify AsyncResult.SetAsCompleted() to set the inner exception (it's already passed the exception causing the completion):
throw new InvalidOperationException("You can set a result only once");
changes to
throw new InvalidOperationException("You can set a result only once", exception);
I don't know what other contexts this may affect, but it seems reasonable....
Another possibility is to break up the try/catch in SftpClient.BeginFileDownload() so asyncResult.SetAsCompleted(exp, false) gets called only if InternalDownloadFile() throws and asyncResult.SetAsCompleted(null, false) gets called otherwise. Something like
bool success = false;
try
{
InternalDownloadFile(path, output, asyncResult, offset =>
{
asyncResult.Update(offset);
if (downloadCallback != null)
{
downloadCallback(offset);
}
});
success = true;
}
catch (Exception exp)
{
asyncResult.SetAsCompleted(exp, false);
}
if (success)
{
asyncResult.SetAsCompleted(null, false);
}
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Inizia da SftpClient.BeginDownloadFile(), InternalDownloadFile() e AsyncResult.SetAsCompleted() per tracciare come vengono intercettate le eccezioni dei callback e come viene contrassegnato il completamento. Confronta gli approcci proposti per preservare le eccezioni e gestire il flusso di controllo; il lavoro è completato quando il fallimento originale del callback rimane individuabile invece di essere oscurato da una seconda InvalidOperationException.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- csharp
- Ambito
- networking
- Tipo di issue
- Bug
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Stato di attività
- Ferma
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 45/100