lunedì 19 marzo 2018

POWERSHELL - ERROR HANDLING - TRAP

Esistono un paio di strategie di gestione degli errori (Error Handling) in PowerShell. Vediamo il primo di una serie di articoli dedicati dall'approfondimento di ciascuna strategia di error handling, valutando i pro ed i contro di ognuna.



Fonte: Powershell troubleshooting guide
di Michael Shepard
ISBN 978-1-78217-357-1

Trap

L'istruzione di Trap è quella più semplice e veloce, introdotta in PowerShell 1.0, eredità la semplicità d'uso del "ON ERROR GOTO" di Visual Basic 6 (ereditando anche le contraddizioni). Il codice contenuto all'interno del blocco di trap viene eseguito a seguito di un problema rilevato nella esecuzione del blocco di codice corrente, ad esempio all'interno di una funzione; vediamo un esempio concreto:
function division{
  Param($a,$b)
  trap{
    write-warning "error!!!"
  }
  return $a/$b
}

istruzione trap: divisione per zero
istruzione trap: divisione per zero

Per accedere ai dettagli dell'errore che ha scatenato il blocco di trap, è sufficiente accedere alla variaible interna $_ , vediamo un esempio:
function division{
  Param($a,$b)
  trap{
    write-warning "error: $_"
  }
  return $a/$b
}

istruzione trap: divisione per zero con dettaglio errore
istruzione trap: divisione per zero con dettaglio errore

Che tipo di Exception?

Ma a che tipo corrisponde la variaible $_ ? utilizziamo il cmdlet get-member per scoprire di più su questa variaible:
function division{
  param($a,$b)
  trap{
    get-member -inputobject $_
  }
  return $a/$b
}


Quindi il tipo della variaible $_ è System.Management.Automation.ErrorRecord al cui interno sono presenti metodi e proprietà per accedere maggiormente nel dettaglio di quale errore si è verificato, ad esempio: per accedere nel dettaglio a quale eccezione ha scatenato il problema è sufficiente accedere alla proprietà Exception della variaible $_.

Break e Continue

Da un blocco trap è possibile proseguire o terminare l'esecuzione sfruttando le keyword break e continue tipiche dei loop. Vediamo un esempio:
function divisionAndMultiply{
  param($a,$b)
  trap{
    write-warning "error: $_"
    continue
  }
  write-output "division" ($a/$b)
  write-output "multiply" ($a*$b)
}

esempio di utilizzo della keyword continue in blocco trap
esempio di utilizzo della keyword continue in blocco trap

Sfruttando la keyword continue, abbiamo inoltre evitato l'output standard dell'errore tramite messaggi rossi sulla console.

Due Trap?

Se in una funzione vengono specificati due blocchi di trap, PowerShell memorizza solo il primo specificato anche nel caso in cui si utilizzi la keyword continue. Vediamo un esempio:
function division{
  param($a,$b)
  trap{
    write-warning "warning!"
    continue
  }
  trap{
    write-warning "error!"
    continue
  }
  return $a/$b
}

Esempio: due blocchi trap
Esempio: due blocchi trap

In questo caso viene eseguito solo il primo blocco trap ignorando il secondo, anche se provvisto di keyword continue. Ma quindi come è possibile intercettare eccezioni differenti?

Trap di eccezioni specifiche

Per poter intercettare una specifica Exception è necessario aggiungere un codice prima del blocco di trap, questo codice è il tipo della Exception da gestire fra parentesi quadre. Vediamo un esempio:
[...]
trap [System.Exception]{
  write-warning "generic exception"
  continue
}
trap [System.IO.FileNotFoundException]{
  write-warning "file not found"
  continue
}
[...]

In questo esempio vengono gestite in maniera diversa una eccezione generica System.Exception e una particolare System.IO.FileNotFoundException. 

Conclusione

PROCONTRO
Velocità di scrittura: è semplice e veloce come il "on errror goto label" del buon vecchio VB6
Essendo simile al goto di VB6 rende il codice difficile da leggere.
Non è possibile inserire due blocchi trap se non specificando quale Exception specifica deve essere gestita
Non è possibile fare trap dentro trap (trap innestati)

Nessun commento:

Posta un commento