Skip to content

Get-LSUpdate returning error: Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (404) Not Found." #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kendall8388 opened this issue May 31, 2023 · 12 comments
Labels
enhancement New feature or request

Comments

@kendall8388
Copy link

kendall8388 commented May 31, 2023

The command Get-LSUpdate had been working in the past days, but now seeing this error: Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (404) Not Found."
...Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (404) Not Found."
At C:\Program Files\WindowsPowerShell\Modules\LSUClient\1.5.5\private\Save-PackageFile.ps1:46 char:9

  •     $webClient.DownloadFile($SourceFile.AbsoluteLocation, $Downlo ...
    
  •     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    • FullyQualifiedErrorId : WebException

When I add additional error handling I get this: An error occurred at line 253 in C:\Program Files\WindowsPowerShell\Modules\LSUClient\1.5.5\public\Get-LSUpdate.ps1:
Exception calling "DownloadFile" with "2" argument(s): "The remote server returned an error: (404) Not Found."

Its showing an error in line 253 of Get-LSUpdate? Any ideas or suggestions?

@DWT-Endpoint
Copy link

I can confirm that we are getting the same error as @kendall8388
I will look at line 253 in C:\Program Files\WindowsPowerShell\Modules\LSUClient\1.5.5\public\Get-LSUpdate.ps1, to see if I can make any sense of it.

@DWT-Endpoint
Copy link

DWT-Endpoint commented Jun 1, 2023

After looking at it more, it appears that the file named: 'https://download.lenovo.com/pccbbs/mobiles/profile_fwnva61.pro' is causing the "404 not found" error.
The file is referenced in: https://download.lenovo.com/pccbbs/mobiles/fwnva61_2_.xml, but the file does not exist, so hence the 404 error when LSUpdate parses the XML, and then tries to download the file.
This seems to be an issue on Lenovo's side of the house, but LSUpdate could/should handle it better.

2023-06-01_16-52-57

NOTE: This seems to be only happening if you wrap Get-LSUpdate in a Try { } Catch { } block, as when the unhandled exception (the 404 error) is encountered, it catches it in the catch block, and exits.

@ghosty212
Copy link

We had the same issue and fixed it by wrapping line 46 in private\Save-PackageFile.ps1 in a try / catch. That seems to fix it, although we don't know whether it has some weird side effects.

diff --git a/private/Save-PackageFile.ps1 b/private/Save-PackageFile.ps1
index 30f4134..7373bda 100644
--- a/private/Save-PackageFile.ps1
+++ b/private/Save-PackageFile.ps1
@@ -43,7 +43,11 @@
         $webClient = New-WebClient -Proxy $Proxy -ProxyCredential $ProxyCredential -ProxyUseDefaultCredentials:$ProxyUseDefaultCredentials
 
         Write-Verbose "Downloading '$($SourceFile.AbsoluteLocation)' to '${DownloadDest}'"
-        $webClient.DownloadFile($SourceFile.AbsoluteLocation, $DownloadDest)
+        try {
+            $webClient.DownloadFile($SourceFile.AbsoluteLocation, $DownloadDest)
+        } catch {
+            write-error $_
+        }
 
         return $DownloadDest
     } elseif ($SourceFile.LocationType -eq 'FILE') {

@dasyak
Copy link

dasyak commented Jun 2, 2023

@ghosty212 thx, saved my life!

@jantari
Copy link
Owner

jantari commented Jun 18, 2023

Thanks for reporting this and thanks @ghosty212 for providing a workaround while I was on vacation 😉

Some files missing in Lenovos' repository and causing 404 errors is not a new problem (See previous issues: #65, #37, #36 and #35) however I'm curious to learn how all of you run LSUClient that this error happening is an issue for you.

This error is non-terminating meaning it gets logged (as it should imo) but LSUClient continues. If your LSUClient scripts exit upon encountering this error I would like to know how exactly you all run LSUClient and Get-LSUpdate in particular. If you use ErrorAction = Stop, exit, trap, throw or other such methods in PowerShell to quit LSUClient entirely on any error then I recommend you not do that (see paragraph 4 of this article in the documentation where I explain why) - but if your scripts don't intentionally quit on any error we'd have to look into why this error being thrown presents an issue for your usecase. So far I have taken the approach that unless an error is so severe that LSUClient cannot continue (in which case I explicitly use throw statements to stop/exit, e.g. a simple example here) it is best if I print the error and continue. This is also the "typical" behavior for most PowerShell cmdlets.

We could merge @ghosty212 edit into the module code, but we would lose some details of the error by re-writing it and another similar error could show up elsewhere making this a whack-a-mole game of adding try-catch to everything.

@jantari
Copy link
Owner

jantari commented Jul 6, 2023

Any further thoughts on this? If not I'm going to keep the behavior as-is and stick to the recommendation of not making your scripts exit on any error.

@ghosty212
Copy link

We used Get-LSUpdate like this

try {
    $updates = Get-LSUpdate | Where-Object { $_.Installer.Unattended }
    $output += "Open Updates: "
    $output += $updates
    $output += $updates | Save-LSUpdate -Verbose
    $output += $updates | Install-LSUpdate -Verbose
} catch {
    $Output += $_
    $NoError = $false
}

So any error thrown should not result in our script terminating, yet it always did.
It seems like Get-LSUpdate doesn't care about the ErrorAction. We tried

try {
    Get-LSUpdate -ErrorAction "continue"
    "No Bug!"
} catch {
    $_
    "Bug!"
}

which should never go into the catch block, but it always did.

After we implemented the change we mentioned earlier, we did not run into that or other problems with the module again. We did around 100 installs on 3 different models.

We installed Windows 10 22H2. Elevated Powershell:

$PSVersionTable
Name                           Value
----                           -----
PSVersion                      5.1.19041.2673
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.2673
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

@jantari
Copy link
Owner

jantari commented Jul 8, 2023

Thanks for the feedback.

The point of a try-catch statement is that it stops and skips to the catch-block as soon as it encounters an exception or terminating error:

try { 'START'; [int]::Parse('z'); 'DONE' } catch { "--> Error caught" }
# prints:
# START
# --> Error caught

The reason -ErrorAction "continue" doesn't work in this case is that the 404 error discussed here is not a PowerShell-native error but a .NET exception thrown by WebClient.DownloadFile(). .NET exceptions cannot be controlled by ErrorAction and always trigger try-catch blocks:

function Test-EAContinue {
  [CmdletBinding()]Param()
  'START'; [int]::Parse('z'); 'DONE'
}

try { Test-EAContinue -ErrorAction Continue } catch { "--> Error caught" }
try { Test-EAContinue -ErrorAction Ignore } catch { "--> Error caught" } # even with Ignore
# always prints:
# START
# --> Error caught

however if you just don't try-catch the error, the code isn't aborted and everything continues normally:

Test-EAContinue -ErrorAction Continue
# prints:
# START
# MethodInvocationException:
# Line |
#    3 |  [int]::Parse('z')
#      |  ~~~~~~~~~~~~~~~~~
#      | Exception calling "Parse" with "1" argument(s): "The input string 'z' was not in a correct format."
# DONE

To get an overview of PowerShells' error types and why certain things work one way and some work differently, this is a great issue to read: MicrosoftDocs/PowerShell-Docs#1583


Are there specific scenarios that made you add try-catch around Get-LSUpdate? In what kind of examples would you want or expect your try-catch to trigger and skip the rest of the code? I am definitely open to improving the error-handling with LSUClient, but I want to understand your preferences as to how you would like it to work. As this doesn't just affect this one part of the code you found, there are definitely more places where a .NET exception could be thrown from I would want to handle it all in a unified and therefore predictable (documentable?) way.

@ghosty212
Copy link

The problem seems to be, that the .NET exception is non-terminating when called without try catch block and terminating when called within try catch.

We have a framework which calls .ps1-files embedded into a try catch block. So we depend of correct handling of powershell erroractions, otherwise each "non terminating" .NET error in LSUClient causes our framework to stop.

@jantari
Copy link
Owner

jantari commented Jul 28, 2023

I see, thanks for the explanation.

I will add the try-catch around this specific DownloadFile call in Save-PackageFile with the next version of LSUClient which will fix this specific issue. But you should still report a problem with whatever framework you use to run PowerShell scripts about this:

We have a framework which calls .ps1-files embedded into a try catch block. So we depend of correct handling of powershell erroractions, otherwise each "non terminating" .NET error in LSUClient causes our framework to stop.

because that is not the normal PowerShell behavior and not always desirable. Whether you want this global try-catch or not should definitely be configurable in the framework by you as it will continue to cause unexpected script terminations in many other scripts and modules.

@jantari
Copy link
Owner

jantari commented Jul 31, 2023

LSUClient 1.6.0 just released and includes the fix for this. Thanks again for your help!

@jantari jantari added enhancement New feature or request and removed fix-in-next-release labels Jul 31, 2023
@DWT-Endpoint
Copy link

Thank you jantari. We will try out your fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants