Timothy Leavitt · Apr 7, 2022 go to post

Here's the problem:

  • I need to do this in a session events class, as I want it to be reusable and apply to all resources in a given web application.
  • If OnStartRequest returns $$$OK, the page renders (%response.Status is set correctly, though).
  • If OnStartRequest returns an error, the web application's error page is shown.

The solution might be using a custom error page too.

Timothy Leavitt · Apr 6, 2022 go to post

So fun fact: in JavaScript, the string "0" is truthy (although the number 0 is falsy). That's what you're seeing here.

Timothy Leavitt · Apr 6, 2022 go to post

@Michael Davidovich you could/should definitely do that validation on the client as well. No need to go to the server to compare two dates.

To work as written, the ObjectScript method itself should return a truthy/falsy result (e.g., quit 0 or quit 1) rather than doing that return in JS.

If you turn on auditing for Terminate, Login, Logout, and Protect events you may see helpful things about what's happening with the JOB command (e.g., if it hits an error).

Timothy Leavitt · Apr 6, 2022 go to post

@Michael Davidovich it might be helpful to look under the hood - specifically, at the class generated for the CSP page ("View Other" in Studio/VSCode).

OnPreHTTP is special in that it runs before the page is rendered (and can e.g. redirect you somewhere else). Generally, I would put code that runs on form submit / POST in OnPreHTTP.

Where you just have <script language="Cache" runat="server">, that'll run as the page is rendered whenever it gets to that block. This would generally be used to render more complex content for which other tag-based CSP options are in sufficient. If you're familiar with PHP, this is equivalent to the <?php ... ?> block in:

<html>
 <head>
  <title>PHP Test</title>
 </head>
 <body>
 <?php echo '<p>Hello World</p>'; ?> 
 </body>
</html>

<script language="Cache" method="SomeMethod"> would be used in hyperevents (i.e., #server(..SomeMethod())# and #call(..SomeMethod())#).

From a coding/design best practices perspective: you should be able to do input validation on the client to provide a friendly error message without needing to go back to the server (e.g., via #server). BUT you should also do validation on the server to make sure that even if the user (maliciously or otherwise) bypasses the client-side validation, they can't submit invalid data.

Timothy Leavitt · Mar 30, 2022 go to post

I've published TestCoverage 2.1.3 on the Open Exchange / zpm - in the situations leading to this, you'll get a more descriptive error message now and the system won't be left in a bad state.

Timothy Leavitt · Mar 30, 2022 go to post

@Michael Davidovich yes we do! It's useful and just in a steady state (although I have a PR in process around some of the recent confusing behavior that's been reported in the community).

Timothy Leavitt · Mar 29, 2022 go to post

On further review, you get a <FUNCTION> error from trying to start the line-by-line monitor when no routines are selected, and the work around is to change namespace to %SYS, do ^PERFMON, and stop the monitor.

USER>zw ##class(%Monitor.System.LineByLine).Start("","",$job)
"0 "_$lb($lb(5002,"<FUNCTION>zStart+45^%Monitor.System.LineByLine.1",,,,,,,,$lb(,"USER",$lb("$^zStart+45^%Monitor.System.LineByLine.1 +1","X^@ +1"))))/* ERROR #5002: ObjectScript error: <FUNCTION>zStart+45^%Monitor.System.LineByLine.1 */

In terms of using the test coverage tool, you should either put a file named coverage.list in your unit test root or pass the list of classes/routines in userParam as described at https://github.com/intersystems/TestCoverage .

https://github.com/intersystems/TestCoverage/issues/11 covers the bad behavior you've seen and would prevent it going forward. (Subsequent attempts to start the line-by-line monitor will end up hitting error #6060 as described in https://github.com/intersystems/TestCoverage/issues/10 .)

Timothy Leavitt · Mar 29, 2022 go to post

Some things that would help diagnose the issue:
write $zv
Modify TestCoverage.Manager to output the following as soon as possible after the error occurs:
write $zu(56,2)

It would also help to know what arguments are being passed to %Monitor.System.LineByLine:Start.

Timothy Leavitt · Mar 21, 2022 go to post

Things I mentioned in the kickoff webinar:

%SQL.AbstractFind/%Library.FunctionalIndex implementations:
Semantic version index:
https://github.com/intersystems-community/zpm/blob/master/src/%25ZPM/Ge…
https://github.com/intersystems-community/zpm/blob/master/src/%25ZPM/Ge…
https://github.com/intersystems-community/zpm/blob/master/src/%25ZPM/Re…
Spatial index: https://github.com/intersystems-ru/spatialindex
Image color index: https://openexchange.intersystems.com/package/iris-image-index-demo
Inspiration for a project:
Implement a hierarchical index that operates on a table with a self-referential field (e.g., an employee table with a manager field) to return (via a %SQL.AbstractFind implementation) all records above (directly/indirectly), below (directly/indirectly), or in the same tree (or graph - need to consider circular references) as a given record.

Timothy Leavitt · Mar 16, 2022 go to post

Here's a sample that loads interoperability system defaults from an XML file:

Class Sample.CCREventHandler Extends %Studio.SourceControl.CCREventHandler
{

/// This method is called during the loading of an ItemSet, after the contents of the ItemSet have been loaded into the namespace, 
/// and after the ImplementCCR routine has been run
Method ItemSetAfterLoadToNS() As %Status
{
    set key = ""
    for {
        set item = ..ItemSetItemList.GetNext(.key)
        quit:(key="")
        if (key [ "backup/ens/defaults.xml") {
            $$$ThrowOnError(##class(Ens.Config.DefaultSettings).%Import(^Sources_"backup/ens/defaults.xml"))
            quit
        }
    }
    Quit ##super()
}

/// This method is called by the CCR Refresh logic, after the items have been refreshed into the namespace.  It is intended for any additional configuration work which 
/// may be necessary (e.g. initialization of reference tables, building of 3rd party sources, etc)
Method RefreshFinalize() As %Status
{
    $$$ThrowOnError(##class(Ens.Config.DefaultSettings).%Import(^Sources_"backup/ens/defaults.xml"))
    Quit ##super()
}

}
Timothy Leavitt · Feb 3, 2022 go to post

Problem in my case is that it's a non-IRIS process, so interactions from IRIS are limited.

Timothy Leavitt · Feb 2, 2022 go to post

I was hoping to avoid something like that. It seems like I run into other issues with what I'm trying to do though around killing the spawned process anyway. I think $zf(-100) just won't do the trick.

Timothy Leavitt · Feb 2, 2022 go to post

I think it's probably going to just come down to using a pipe/command pipe/etc. instead of $zf(-100).

Timothy Leavitt · Feb 2, 2022 go to post

What I'm trying to do is manage the process spawned with $zf(-100) from ObjectScript. In short, if the ObjectScript process is killed or <INTERRUPT>ed (which you can't do while in a ZF state), I want to kill the spawned process as well.

More specifically, I have a main ObjectScript process that's monitoring an Angular build. It spawns another ObjectScript process that used to just call $zf(-100) synchronously to run a build script. This other process would then notify the parent via $System.Event when it's done. Normally this build script will run for a finite period of time, but I'm looking to run an Angular build with the --watch flag and terminate it when the user Ctrl+C's in Terminal.

Timothy Leavitt · Jan 24, 2022 go to post

I've updated my original post with a bit of performance analysis as well (couldn't resist) - I'm curious if anyone has ideas for getting an embedded SQL approach even closer to raw global refs. :)

Timothy Leavitt · Jan 21, 2022 go to post

I'm not aware of any JSON schema capability.

%Dictionary has two sets of classes: *Definition and Compiled*. If you want to see inherited members you need to look at Compiled* (e.g., CompiledClass / CompiledProperty). If you want to know from which class, there's an "Origin" property.