This question already has answers here:
Try/catch does not seem to have an effect
(7 answers)
Closed 3 years ago.
I am trying to handle setting a PowerShell variable from a registry key.
So I use a try{} catch {} to get rid of eventual errors in case the key doesn't exists. However, I still get the error output on console.
$ZZ_ConVTL = try { (Get-ItemProperty -path "HKCU:\Console" -name VirtualTerminalLevel).VirtualTerminalLevel } catch { "N/A" }
...
# Output:
Get-ItemProperty : Property VirtualTerminalLevel does not exist at path HKEY_CURRENT_USER\Console.
At C:\Users\Administrator\Documents\xxxx\xxxx.ps1:181 char:32
+ ... = try { (Get-ItemProperty -path "HKCU:\Console" -name VirtualTermi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (VirtualTerminalLevel:String) [Get-ItemProperty], PSArgumentException
+ FullyQualifiedErrorId : System.Management.Automation.PSArgumentException,Microsoft.PowerShell.Commands.GetItemPropertyCommand
How can I handle and avoid this error from showing up in the console?
What your Get-ItemProperty call emits is a non-terminating error, whereas try / catch only catches terminating errors.
Non-terminating errors are far more common that terminating ones.
Use common parameter -ErrorAction Stop to promote (the first) non-terminating error generated by a cmdlet to a terminating one that try / catch handles.
You can generally achieve the same effect by setting preference variable
$ErrorActionPreference = 'Stop' beforehand, but note that doing so has no effect on calls to external programs and on functions implemented in modules.
See also:
The about_Try_Catch_Finally help topic.
A description of the fundamental error types in the context of guidance for command authors on when to emit a terminating vs. a non-terminating error: this answer.
A comprehensive overview of PowerShell's surprisingly complex error handling: this GitHub docs issue.
Related
When I was running a process in ProcessMaker, I got error message "Fatal error in trigger", then I checked the error logs and found this
PHP Parse error: syntax error, unexpected '}' in /opt/processmaker/workflow/engine/classes/class.pmScript.php(216) : eval()'d code on line 9.
Could anyone tell me please what should I do?
Thank you so much for your help.
Here's the code :
public function executeAndCatchErrors($sScript, $sCode)
{
ob_start('handleFatalErrors');
set_error_handler('handleErrors');
$_SESSION['_CODE_'] = $sCode;
eval($sScript );
$this->evaluateVariable();
unset( $_SESSION['_CODE_'] );
ob_end_flush();
}
ProcessMaker supports Triggers, where you can embed PHP code directly into a workflow process.
The code you have pasted is actually part of the ProcessMaker source code, which evaluates the triggers during the execution of a workflow process.
It appears though there is a PHP syntax error in a trigger rather than the source code itself.
In order to fix this issue, I would look at the process triggers and check for PHP syntax errors. I would also try and run through the process and see at what point you get the error and then check the triggers that are defined around the task that caused the error.
For more information on triggers, see:
https://wiki.processmaker.com/3.0/Triggers
I am looking for a manifest to start a service on windows server if the service exists.
I am looking to check a service with a condition if the file exists.
service { 'test service':
ensure => 'running',
enable => true,
unless => 'if((test-path "C:\Program Files\test1") -or (test-path "C:/Program Files/test2")){ exit 0 } else { exit 1 }',
provider => powershell,}
Above code returns an error that unless is an invalid parameter. Any other way to check?
Thanks a lot!!
it doesn't look like the service resource has a parameter to support conditional inclusion. Puppet also does not have an easy way to check for the existence of a file on the client that I'm aware of. I have gotten around this by creating a custom fact that checked the condition I needed and then wrapping the resource in an unless block:
unless $facts['test_file_exists'] {
service { 'test service':
ensure => 'running',
enable => true,
}
since a custom fact can be written in any language that can output "key=value" pairs to stdout you could use your existing powershell code as a fact with a small change:
if((test-path "C:\Program Files\test1") -or (test-path "C:\program Files\test2")){
write-host "test_file_exists=true
}
else{
write-host "test_file_exists=false"
}
there are a few different ways to distribute the fact out to your client systems. I prefer to put the fact into a module and let pluginsync distribute it out for me. If you don't want to include it in a module then you would have to find some way to get the powershell code into C:\ProgramData\PuppetLabs\facter\facts.d\ with the proper .ps1 extension on the end.
I'm trying to test some different queries in an F# script file against my Azure CosmosDb, but I'm getting an error regarding a missing DLL when I try to execute a query itself.
I'm loading the Documents.Client.dll:
#r "../packages/Microsoft.Azure.DocumentDB/lib/net45/Microsoft.Azure.Documents.Client.dll"
open Microsoft.Azure.Documents
open Microsoft.Azure.Documents.Client
open Microsoft.Azure.Documents.Linq
But when I execute a query:
Seq.toList <| query {
//some query that I copy & pasted from a working file
}
I get this error:
System.AggregateException: One or more errors occurred. ---> System.DllNotFoundException: Unable to load DLL 'Microsoft.Azure.Documents.ServiceInterop.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
at Microsoft.Azure.Documents.ServiceInteropWrapper.CreateServiceProvider(String configJsonString, IntPtr& serviceProvider)
at Microsoft.Azure.Documents.Query.QueryPartitionProvider.Initialize()
at Microsoft.Azure.Documents.Query.QueryPartitionProvider.GetPartitionedQueryExecutionInfoInternal(SqlQuerySpec querySpec, PartitionKeyDefinition partitionKeyDefinition, Boolean requireFormattableOrderByQuery, Boolean isContinuationExpected)
at Microsoft.Azure.Documents.Query.DocumentQueryExecutionContextBase.<GetPartitionedQueryExecutionInfoAsync>d__0.MoveNext()
(there is more in the stack trace - this is just the top of it).
I can't find the ServiceInterop dll anywhere - it's not referenced in any projects or in my packages folder, and it's not a nuget reference. I'm not sure what I could be missing to only get this error in F# Interactive.
Update
Following the advice in the comments from #tomislav-markovski, I changed the version of Microsoft.Azure.DocumentDB to 1.13.2. This does create the ServiceInterop dll in the package folder, but now running my query in F# interactive gives this output:
--> Referenced 'c:\VSTS\MyApplication\../packages/Microsoft.Azure.DocumentDB/lib/net45/Microsoft.Azure.Documents.Client.dll' (file may be locked by F# Interactive process)
Script.fsx(5,1): error FS0229: Error opening binary file 'c:\VSTS\MyApplication\../packages/Microsoft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll': c:\VSTS\MyApplication\../packages/Micro
soft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll: bad cli header, rva 0
Script.fsx(5,1): error FS3160: Problem reading assembly 'c:\VSTS\MyApplication\../packages/Microsoft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll': Exception of type 'Microsoft.FSharp.Compiler.ErrorLogger+
StopProcessingExn' was thrown.
The "File may be locked" error seems like it's important, but I closed & reopened VSCode to make sure that instance of F# Interactive wasn't holding on to anything. I am referencing the Service Interop file:
#r "../packages/Microsoft.Azure.DocumentDb/runtimes/win7-x64/native/Microsoft.Azure.Documents.ServiceInterop.dll"
If I remove this, the above errors go away... and I go back to the query itself crashing because of the missing DLL.
Update 2
I've tried a few additional things:
Absolute instead of relative pathing to the Client.dll. This results in the "missing service interop dll" error.
Absolute instead of relative pathing to the 'ServiceInterop.dll'. This results in the "error opening binary file" error.
Using #I to load the DLL with easier pathing:
#I "../packages/Microsoft.Azure.DocumentDB/lib/net45/"
#r "Microsoft.Azure.Documents.Client.dll"
Results in the same "missing ServiceInterop.dll" error.
Simplifying the query:
Seq.toList <| query {
for t in client.CreateDocumentQuery( documentCollectionUri()) do
select t
}
This resulted in the same "missing ServiceInterop.dll" error.
5. Using FeedOptions with "Enable Cross Partiiton Query" on:
let feedOptions = FeedOptions()
feedOptions.EnableCrossPartitionQuery <- true
feedOptions.MaxItemCount <- 3 |> System.Nullable
Seq.toList <| query {
for t in client.CreateDocumentQuery( documentCollectionUri(), feedOptions ) do
select t
}
As you can see, I also tried setting the max item count. Both of these gave the same "missing ServiceInterop.dll" error.
The closest thing to a solution for this that I was able to find was to add the location of the ServiceInterop.dll to the Path environment variable for the duration of the FSI session, something like so:
open System
open System.IO
// get existing contents of path env var
let path = Environment.GetEnvironmentVariable("Path")
// get location where nuget puts the service interop dll
let serviceInteropDir = #C:\User\<USERNAME>\.nuget\packages\microsoft.azure.documentdb.core\1.9.1\runtimes\win\native"
// add service interop location to the end of the path
let newPath = path + ";" + serviceInteropDir
// update the path env var with the new path
Environment.SetEnvironmentVariable("Path", newPath)
NOTE: Notice I am using version 1.9.1 of the DocumentDB.Core package. There seems to be a strong naming problem with the 1.10.0 version of the DocumentDB.Core package, so avoid that version until a fix is released or a workaround is found.
I need to execute some operation on a PS script that should be ran in parallel. Using PS Jobs is not a real option since the tasks that must be paralized depends on custom functions that are defined inside a separete Module. Although I know that I can use the -InitializationScript flag and import the module that contains my custom function, I think that I loose speed since importing the hole module is "time consuming" operation.
Bearing in mind all those things I'm trying launching those "tasks" in separate threads that share the runspace. My code looks like:
$ps = [Powershell]::Create().AddScript({ Get-CustomADDomain -dnsdomain $env: })
$threadRes = $ps.beginInvoke()
$ps.EndInvoke($threadRes)
The drawback of this approach is that, since I'm creating a new "powershell process" this runspace do not have my custom modules loaded and thus I'm in the same situation that I got with Jobs.
If I try to attach current runspace to the newly created $ps by using following code:
$ps = [Powershell]::Create()
$ps.runspace = $host.runspace
$ps.AddScript({ Get-CustomADDomain -dnsdomain $env: })
$threadRes = $ps.beginInvoke()
$ps.EndInvoke($threadRes)
I get an error because I'm trying to close current pipeline (bad thing).
I think my second shot is on the right way but I cannot retrieve results from the invocation of the script, or at least I'm not able to see the way to do it.
It's obvious that I must missing something so any advice you may have will be very appretiated!!!!
A new job or runspace isn't going to inherit functions from a module that was imported into the current session. That being said, you don't have to import the entire module. If you've got specific functions in the current session you need to have available in the job, you can add just those functions like this:
function test_function {'This is a test'}
function test_function2 {'This is also a test'}
$job_functions = 'test_function','test_function2'
$init = [scriptblock]::Create(
$(foreach ($job_function in $job_functions)
{
#"
function $job_function
{$((get-item function:$job_function).definition)}
"#
}))
$init
function test_function
{'This is a test'}
function test_function2
{'This is also a test'}
I'm trying to generate a custom error page for my xpages. I googled a lot of solutions and so far I get an error page telling me, that an error occured.
But I can't get the information what exactly happened (in this case the error is, that an "doc" has to be saved, but i named the variable "docs" just to get error).
All I do is:
var errObj = requestScope.error;
output = errObj.getCause().getErrorPropertyId();
output = errObj.getCause().getComponentId();
As soon as I try to call getExpressionText() I get an error 500.
How do I get the information, where the error happened (line number) and the variable that caused the error? - just like I do using the standard error page.
The error line and details are not easily accessible from requestScope.error. If you look at the source code for the latest release of Mark Leusink's Debug Toolbar, you'll see he's parsing the stack trace to get the details.
However, you can access all the relevant information using the underlying Java class for the SSJS exception - com.ibm.jscript.InterpretException using getErrorLine(). The getLocalizedMessage() method gets the error detail that usually starts "Script interpreter error". The getExpressionText() method retrieves the line that threw the error.
If you take a look at the XPages OpenLog Logger project I put on OpenNTF, that's what I use to log full details to OpenLog. http://www.openntf.org/Internal/home.nsf/project.xsp?action=openDocument&name=XPages%20OpenLog%20Logger
You can see the source code of the OpenLogPhaseListener which uses those methods here: https://github.com/paulswithers/openlogjava/blob/master/OpenLogJava/WebContent/WEB-INF/src/com/paulwithers/openLog/OpenLogPhaseListener.java
Even if you're not a Java expert, from use of SSJS the key parts should be understandable. Line 84 captures uncaught exceptions - when XPages routes to the default error page. That uses the methods I mentioned.
Lines 98 to 105 are the ones that log out all the details if you just use a catch block, passing OpenLogBean.addError(e, this) where e is the error object and this is the component the error occurs on. error.getError() in the Java code retrieves that error object. To get the typeahead in SSJS you'll need to use catch(e:com.ibm.jscript.InterpretException) I believe.
I haven't tested this, I've just working back from what I used for the project on OpenNTF.
Have a look at this XSnippet by Tony McGuckin: http://openntf.org/XSnippets.nsf/snippet.xsp?id=custom-error-page-cw-cause-and-stacktrace-information. It uses the following to output details on the error:
var output = requestScope.error.toString()+"\n\n";
if(requestScope.error instanceof com.ibm.xsp.exception.XSPExceptionInfo){
var codeSnippet = requestScope.error.getErrorText();
var control = requestScope.error.getErrorComponentId();
var cause = requestScope.error.getCause();
output += "In the control : " + control + "\n\n";
if(cause instanceof com.ibm.jscript.InterpretException){
var errorLine = cause.getErrorLine();
var errorColumn = cause.getErrorCol();
output += "At line " + errorLine;
output += ", column " + errorColumn + " of:\n";
}else{
output += "In the script:\n";
}
output += codeSnippet;
}
return output;
For now I've dealt with this problem by using the Debug Toolbar and the OpenLog Database.
If an error occurs the user only gets a custom error page (using the example of the Debug Toolbar) with the information, that something went wrong. So he does not have to bother with any other problems or even the Stack Trace. But at the same moment he gets the error page, the error is logged in our Log-Database with all informations needed (like line, exact error message etc.).
I've also implemented an "Report this problem" Link-Button to create a new E-Mail containing important information about the session the user is currently in.