Tuesday, June 30, 2020

Kotlin JS should usually catch Throwable

As I worked on starting a Node application in Kotlin JS, I found that one of my endpoints failed when tested by Invoke-WebRequest with an error about an incomplete response. I knew this indicated a crash in my endpoint handler, but it was not obvious how to get details on what went wrong. A try-catch block to handle Exceptions did not catch anything. Changing the catch block to handle all Throwables, however, caught the problem and was able to display it.

Monday, June 29, 2020

Converting between coroutines and promises in Kotlin JS

Most modern JavaScript libraries handle asynchronicity by passing around "promise" objects that can be chained together to make a workflow with several suspension points. These are perfectly usable in Kotlin JS, but it would be even nicer if Kotlin's excellent support and cleaner syntax for coroutines and suspending functions could be used.

In a coroutine, a promise can be awaited (i.e. its behavior called in a suspending manner) with its await() extension function, which suspends. A coroutine context can be turned into a promise object by putting the suspending code inside a GlobalScope.promise block (or that of any other CoroutineScope). Such promises can be used by plain JavaScript code.

Sunday, June 28, 2020

"getsockname failed: Not a socket" on Windows

New Windows 10 versions come with a Windows port of OpenSSH, so ssh can be done from the Windows command line even outside Bash on Ubuntu on Windows. I tried to set up connection reuse (ControlMaster and ControlPath directives in the SSH configuration), but then found that all connections to my specifed host failed with "getsockname failed: Not a socket." If I understand correctly, OpenSSH is trying to use UNIX sockets to coordinate between ssh processes. Alas, it cannot figure out how to use sockets on Windows. As far as I can tell, SSH connection reuse does not currently work on Windows.

Saturday, June 27, 2020

No clear way to store resources in Kotlin JS projects

I'm working on a Node JS application written in Kotlin with the new Kotlin JS plugin. I needed to include some static files (web page templates) with the application, but it is not at all clear how I should connect them to the project. Gradle created a resources folder, but items in it didn't seem to be copied to anywhere in the build output. It looks like the old Kotlin2Js plugin worked with Webpack for deployment (?), but I see no such configuration or build step in my project. So I rigged up a post-compile step to just copy all the resources to the same folder as the compiled JavaScript files:
tasks.getByName("compileKotlinJs") {
    val resFolder = project.file("src/main/resources")
    inputs.dir(resFolder)
    doLast("copy resources") {
        resFolder.copyRecursively(project.file("build/js/packages/${project.name}/kotlin"), true)
    }
}

Friday, June 26, 2020

Invoke-WebRequest can work when curl doesn't

I'm working on a Node JS app hosted in Namecheap's shared hosting. I rigged up a test POST endpoint to make sure I configured everything correctly then tried to access it with a cURL invocation on the command line. That failed with a 404 and an Express message stating that it couldn't GET a document that looks likely to be used for 403 Forbidden errors. (It took an unfortunate amount of time to realize that it was an Express error page - I first assumed requests weren't being routed to the Node JS app at all.) Bizarrely, the equivalent Invoke-WebRequest command in PowerShell worked. It looks like cURL's request offended a "security" feature provided by Namecheap. Specifically, it provided different headers:

POST /endpoint HTTP/1.1
Host: example.com
User-Agent: curl/7.55.1
Accept: */*

In contrast to PowerShell's request:

POST /endpoint HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.19041.1
Content-Type: application/x-www-form-urlencoded
Host: example.com
Content-Length: 0
Connection: Keep-Alive

Monday, June 15, 2020

Get-Content string values have file information stapled to them

Today I wrote a quick PowerShell script that involved reading lines from a file with Get-Content and putting each into an object that was later serialized with ConvertTo-Json. To my surprise, instead of lines being serialized as standard JSON strings, they become JSON objects with a "value" property and several others describing the file the line came from. I checked the line variable's type with .GetType() and it was a standard string. Piping it to Get-Member, however, showed that it had several NoteProperty members. Note properties can be associated with arbitrary objects. They don't touch the actual .NET object, but PowerShell keeps track of them and ConvertTo-Json serializes them. It's strange (IMO) for Get-Content to staple this information to every line string since I'd expect transformation to a different serialization format to be a common task. I worked around it by calling .ToString() on the annotated string object to get an unannotated copy.

Monday, June 8, 2020

The kotlin.js plugin obsoletes kotlin2js

I tinkered with a new Kotlin for JavaScript project today and ran into some confusion. The documentation I found frequently mentioned features that didn't seem to be recognized by Gradle and third-party examples did a lot of things that I wouldn't have expected to be necessary. Older documentation mentioned applying a kotlin2js plugin, which apparently had a lot of features but is deprecated in favor of the new Kotlin JS plugin that is applied by default when creating a Kotlin/JS project in IntelliJ. Alternatively, it can be added as a plugin with kotlin("js")

Manual Node setup doesn't seem to be necessary. Dependencies from NPM can be added with implementation(npm(artifact, version)) in the standard dependencies block. I have not yet found a good way to package and deploy for NodeJS, though.

Wednesday, June 3, 2020

Theming the PCKF

This past week I spent some time customizing the theme of the Keen forum. A new theme was long overdue from the migration to phpBB 3. I started by just replacing a bunch of CSS colors to a green-and-yellow theme like the previous forum, which helped a lot by itself. Community members suggested other adjustments including a header background image from the game. That took some fiddling to get right but looks really good!

Monday, June 1, 2020

Policy Plus - Versioning with Git

For a long time, Policy Plus's Help | About dialog stated that the program had no version number because the project was in early development. The development is no longer so early, and I received a request to release stable binaries, so it seemed like time to add a version system. Since Policy Plus isn't at 1.0 yet, I'm not ready to start issuing normal version numbers. Instead, each Git commit can represent a version. I rigged up a batch file to write the current tag or commit into a file that gets compiled into the program and used to show the version. I then released the May2020 snapshot.