How to catch terminating error and still continue

2019-08-19 02:32发布

I need a bit of your help to improve my script and handle exceptions correctly. I have a script to delete lines in a .log file using date comparison to define if it's older enough and if true, line is deleted. Here is the part of the script where i need help:

Foreach ($Fichier in $Fichiers)
{
    try
    {
        (Get-Content $Fichier) |
            Where-Object {$_} |
            Where-Object { ([datetime]::ParseExact(([string]$_).Substring(0,19), $Format, $Culture) -ge (Get-Date).AddDays(-$Jours)) } |
            Set-Content $Fichier
        LogMessage -Message "Fichier $Fichier purgé des toutes les lignes datant de plus de $Jours jours"
    }
    catch
    {
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        LogMessage -Message "$FailedItem - $ErrorMessage"
    }
}

The problem is my .log have lines like these

[ 30-10-2017 16:38:11.07 | INFO    | XXX.ActiveMQ.ConsumerService.Business.TransactionConsumerTopic | WriteMessageToDlq    ] - Le traitement du message ID:XXXXX-56720-1509361559247-13:1:1:1:1 a rencontré une erreur côté Web Service : TKO / JMS_3.9.47612_2017-10-30 16:38:00.937_TKO / 3.9.47612 / 2017-10-30 16:38:00.937 / 
[1];Erreur non-gérée : Une erreur applicative est survenue.

As you can see, the first line is OK for my script, it makes the Substring and the date comparison, but sometimes in the file, you have that second line which is not OK because it throws an error, a terminating error because my script doesn't continue

Exception lors de l'appel de « ParseExact » avec « 3 » argument(s) : « La chaîne n'a pas été reconnue en tant que DateTime valide. »

I try to find a way to go next line if the date comparison raises an error. i have also tried that way after the comment of @Luka-Klarić

try
    {
        (Get-Content $Fichier) |
            Where-Object {$_} |
            Where-Object { ([datetime]::ParseExact(([string]$_).Substring(0,19), $Format, $Culture) -ge (Get-Date).AddDays(-$Jours)) } -ErrorAction SilentlyContinue |
            Set-Content $Fichier
        LogMessage -Message "Fichier $Fichier purgé des toutes les lignes datant de plus de $Jours jours"
    }
    catch
    {
        $ErrorMessage = $_.Exception.Message
        $FailedItem = $_.Exception.ItemName
        LogMessage -Message "$FailedItem - $ErrorMessage"
        Continue
    }

But it's not working too. Any help is appreciated for a PowerShell noob like me and ask if you need further information.

EDIT : I have change the approach for that problem and i found a solution this way -> Purge with PowerShell a big log file by deleting line by line and stopping it when my date comparison is true

2条回答
Fickle 薄情
2楼-- · 2019-08-19 03:12

Normaly try{}catch{} avoid your program to stop :

$dates = "05/12/2012", "5/12/2012", "05/12/2012"
foreach($date in $dates){try{[datetime]::ParseExact($date, "dd/mm/yyyy", $null )}catch{}}

The second date generate an exception but the script still go on.

查看更多
闹够了就滚
3楼-- · 2019-08-19 03:31

So if I'm understanding right, you're wondering why LogMessage -Message "Fichier $Fichier purgé des toutes les lignes datant de plus de $Jours jours"fails to run when you hit a terminating error?

If that's the case it is because the try{}catch{} moves immediately to the catch then immediately past the block to continue along.

If you need that line to run even in case of an error, put it in the catch block, or look into a trap{} which would resume from the next line of code, unlike a try{}catch{}

edit:

try
{
    write-host "line 1" -ForegroundColor Magenta
    throw "custom"
    write-host "line 2" -ForegroundColor Magenta
}
catch
{
    write-host "womp womp" -ForegroundColor Red
}

vs:

trap
{
    write-host "womp womp" -ForegroundColor Red
}    

write-host "line 1" -ForegroundColor Magenta
throw "custom"
write-host "line 2" -ForegroundColor Magenta

these examples might help unless its more complicated than I'm understanding.

查看更多
登录 后发表回答