Skip to content

Commit 1d7b1f3

Browse files
committed
fix: better error handling
1 parent baec976 commit 1d7b1f3

1 file changed

Lines changed: 98 additions & 40 deletions

File tree

powershell/yt-download.ps1

Lines changed: 98 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -70,28 +70,61 @@ function Play-Sound {
7070
}
7171

7272
function TerminateWithError {
73-
param(
74-
[string]$errorMessage = "Error happened.`nEXIT",
75-
[System.Exception]$exception
73+
param (
74+
[string]$ErrorMessage = "Error happened",
75+
[System.Management.Automation.ErrorRecord]$ErrorRecord
7676
)
7777

7878
if ($PlaySound) {
7979
Play-Sound -Action Error
8080
}
8181

82-
if ($exception) {
83-
$line = $_.InvocationInfo.ScriptLineNumber
82+
if ($ErrorRecord) {
83+
Write-Host "`n $ErrorMessage `n" -BackgroundColor DarkRed -ForegroundColor White
84+
85+
# Step 1: Display primary exception
86+
$currentException = $ErrorRecord.Exception
87+
$primaryLine = $ErrorRecord.InvocationInfo.ScriptLineNumber
8488

85-
if ($line) {
86-
Write-Host "`n$errorMessage :`n`t$($exception.Message)`n`tLine: $line`nEXIT" -ForegroundColor Red
89+
if ($primaryLine) {
90+
Write-Host "Error at line: $primaryLine" -ForegroundColor Red
8791
}
88-
else {
89-
Write-Host "`n$errorMessage :`n$($exception.Message)`nEXIT" -ForegroundColor Red
92+
93+
$lastMessage = $null
94+
if ($currentException) {
95+
Write-Host "$($currentException.Message)" -ForegroundColor Yellow
96+
$lastMessage = $currentException.Message
9097
}
98+
99+
# Step 2: Traverse inner exceptions with deduplication logic
100+
while ($currentException.InnerException) {
101+
$currentException = $currentException.InnerException
102+
103+
$innerLine = $null
104+
if ($currentException.ErrorRecord -and $currentException.ErrorRecord.InvocationInfo) {
105+
$innerLine = $currentException.ErrorRecord.InvocationInfo.ScriptLineNumber
106+
}
107+
108+
# Deduplicate: skip if the message is identical and provides no new line context
109+
if ($currentException.Message -eq $lastMessage -and -not $innerLine) {
110+
continue
111+
}
112+
113+
Write-Host "`n-> Caused by inner exception:" -ForegroundColor DarkGray
114+
if ($innerLine) {
115+
Write-Host "Error at line: $innerLine" -ForegroundColor Red
116+
}
117+
118+
Write-Host "$($currentException.Message)" -ForegroundColor Yellow
119+
$lastMessage = $currentException.Message
120+
}
121+
122+
Write-Host "`n EXIT " -BackgroundColor DarkRed -ForegroundColor White
91123
}
92124
else {
93-
Write-Host "ERROR`n" -ForegroundColor Red
94-
Write-Host " $errorMessage`n`nEXIT" -ForegroundColor Red
125+
Write-Host "`n ERROR `n" -BackgroundColor DarkRed -ForegroundColor White
126+
Write-Host "$ErrorMessage" -ForegroundColor Yellow
127+
Write-Host "`n EXIT " -BackgroundColor DarkRed -ForegroundColor White
95128
}
96129

97130
exit 1
@@ -491,7 +524,7 @@ if ($url -and -not $install -and -not $uninstall) {
491524

492525
}
493526
catch {
494-
TerminateWithError -errorMessage "Error while processing URL" -exception $_.Exception
527+
TerminateWithError -errorMessage "Error while processing URL" -ErrorRecord $_
495528
}
496529

497530
<#*==========================================================================
@@ -518,10 +551,12 @@ if ($url -and -not $install -and -not $uninstall) {
518551
Write-Host "- Download file in (unless if handled by YDL-UI.exe): $DL_DIR" -ForegroundColor Green
519552
}
520553
else {
521-
TerminateWithError -errorMessage "The DOWNLOAD_DIR set in yt-dlp userscript : `"$DL_DIR`" doesn’t exist."
554+
Write-Host "The DOWNLOAD_DIR set in yt-dlp userscript (Tampermonkey) : `"$DL_DIR`" doesn’t exist." -ForegroundColor Yellow
555+
Write-Host "Trying fallback…" -ForegroundColor Yellow
556+
$Script:DOWNLOAD_DIR_fallback = $true
522557
}
523558
}
524-
else {
559+
if ($DOWNLOAD_DIR_fallback -or -not $parameters.ContainsKey('dldir')) {
525560
$script:DL_DIR = $FullDownloadDir
526561
if (Test-Path -Path $DL_DIR -PathType Container) {
527562
Write-Host "- Download file in (unless if handled by YDL-UI.exe): $DL_DIR" -ForegroundColor Green
@@ -536,7 +571,7 @@ if ($url -and -not $install -and -not $uninstall) {
536571
Write-Host " Success: Folder created at `"$($NewFolder.FullName)`"`n" -ForegroundColor Green
537572
}
538573
catch {
539-
TerminateWithError -errorMessage "Failed to create the folder `"$DownloadFolderName`" in `"$DownloadsPath`"." -exception $_.Exception
574+
TerminateWithError -errorMessage "Failed to create the folder `"$DownloadFolderName`" in `"$DownloadsPath`"." -ErrorRecord $_
540575
}
541576
}
542577
}
@@ -690,7 +725,7 @@ if ($url -and -not $install -and -not $uninstall) {
690725
* ℹ Handle select downloaded file in Windows
691726
===========================================================================#>
692727
if ($IsWindows) {
693-
# Définition de l'API Windows native via C#
728+
# Setting native Windows API via C#
694729
$Win32Signature = @'
695730
[DllImport("shell32.dll", ExactSpelling = true)]
696731
public static extern int SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string pszName, IntPtr pbc, out IntPtr ppidl, uint sfgaoIn, out uint psfgaoOut);
@@ -705,35 +740,50 @@ public static extern void CoTaskMemFree(IntPtr pv);
705740
$ShUtils = Add-Type -MemberDefinition $Win32Signature -Name "ShellUtils" -Namespace "Win32API" -PassThru
706741

707742
function Show-InFileManager {
743+
[CmdletBinding()]
708744
param (
709745
[string]$FilePath
710746
)
711747

712-
$AbsolutePath = (Resolve-Path -Path $FilePath -ErrorAction Stop).Path
713-
714-
# 1. Obtenir le PIDL (Pointer to an Item ID List) du fichier ciblé
715-
$Pidl = [IntPtr]::Zero
716-
$SfgaoOut = 0
717-
$Result = $ShUtils::SHParseDisplayName($AbsolutePath, [IntPtr]::Zero, [ref]$Pidl, 0, [ref]$SfgaoOut)
718-
719-
if ($Result -eq 0 -and $Pidl -ne [IntPtr]::Zero) {
748+
process {
720749
try {
721-
# 2. Appeler l'API native.
722-
# En passant le PIDL du fichier en premier argument et 0 en nombre d'éléments enfants,
723-
# Windows (ou DOpus via interception) ouvre le dossier parent et sélectionne le fichier.
724-
[void]$ShUtils::SHOpenFolderAndSelectItems($Pidl, 0, $null, 0)
725-
}
726-
finally {
727-
# 3. Libérer la mémoire managée requise par l'API COM/Shell
728-
if ($Pidl -ne [IntPtr]::Zero) {
729-
$ShUtils::CoTaskMemFree($Pidl)
750+
$AbsolutePath = (Resolve-Path -Path $FilePath -ErrorAction Stop).Path
751+
# 1. Obtenir le PIDL (Pointer to an Item ID List) du fichier ciblé
752+
$Pidl = [IntPtr]::Zero
753+
$SfgaoOut = 0
754+
$Result = $ShUtils::SHParseDisplayName($AbsolutePath, [IntPtr]::Zero, [ref]$Pidl, 0, [ref]$SfgaoOut)
755+
756+
if ($Result -eq 0 -and $Pidl -ne [IntPtr]::Zero) {
757+
try {
758+
# 2. Appeler l'API native.
759+
[void]$ShUtils::SHOpenFolderAndSelectItems($Pidl, 0, $null, 0)
760+
}
761+
finally {
762+
# 3. Libérer la mémoire managée requise par l'API COM/Shell
763+
if ($Pidl -ne [IntPtr]::Zero) {
764+
$ShUtils::CoTaskMemFree($Pidl)
765+
}
766+
}
767+
}
768+
else {
769+
# Sécurité si l'API échoue : retour à la méthode basique
770+
Start-Process explorer.exe -ArgumentList "/select,`"$AbsolutePath`""
730771
}
731772
}
773+
catch {
774+
# Pass $_.Exception as the InnerException to preserve the original root cause
775+
$exception = [System.Management.Automation.RuntimeException]::new("File manager failed to open.", $_.Exception)
776+
$errorRecord = [System.Management.Automation.ErrorRecord]::new(
777+
$exception,
778+
"FileManagerError",
779+
[System.Management.Automation.ErrorCategory]::NotSpecified,
780+
$null
781+
)
782+
783+
$PSCmdlet.ThrowTerminatingError($errorRecord)
784+
}
732785
}
733-
else {
734-
# Sécurité si l'API échoue : retour à la méthode basique
735-
Start-Process explorer.exe -ArgumentList "/select,`"$AbsolutePath`""
736-
}
786+
737787
}
738788
}
739789

@@ -866,12 +916,20 @@ public static extern void CoTaskMemFree(IntPtr pv);
866916
if (Test-Path $TempPathFile) {
867917
$DownloadedFilePath = (Get-Content -Path $TempPathFile -Raw).Trim()
868918
Remove-Item -Path $TempPathFile -ErrorAction SilentlyContinue
869-
Write-Host "DownloadedFilePath : `"$DownloadedFilePath`"" -ForegroundColor Yellow
870919
}
871920

872921
# Apply file selection logic
873922
if ($DownloadedFilePath) {
874-
Show-InFileManager -FilePath $DownloadedFilePath
923+
Write-Host "DownloadedFilePath : `"$DownloadedFilePath`"" -ForegroundColor Yellow
924+
try {
925+
Show-InFileManager -FilePath $DownloadedFilePath
926+
}
927+
catch {
928+
TerminateWithError -ErrorMessage "Show-InFileManager failed" -ErrorRecord $_
929+
}
930+
}
931+
else {
932+
TerminateWithError '$DownloadedFilePath was not find in $TempPathFile'
875933
}
876934
}
877935
}
@@ -985,7 +1043,7 @@ if ($install) {
9851043
Write-Host "`nINSTALLATION COMPLETE" -ForegroundColor Green
9861044
}
9871045
catch {
988-
TerminateWithError -errorMessage "Failed to add protocol '$protocol`://' into the registry" -Exception $_.Exception
1046+
TerminateWithError -errorMessage "Failed to add protocol '$protocol`://' into the registry" -ErrorRecord $_
9891047
}
9901048

9911049
}

0 commit comments

Comments
 (0)