@@ -70,28 +70,61 @@ function Play-Sound {
7070}
7171
7272function TerminateWithError {
73- param (
74- [string ]$errorMessage = " Error happened. `n EXIT " ,
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`t Line: $line `n EXIT " - 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 ) `n EXIT" - 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`n EXIT" - 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)]
696731public 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 " `n INSTALLATION 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