From c242bbeba8a9819bd0815643868ce16dd00090e2 Mon Sep 17 00:00:00 2001 From: Wouter Hendriks Date: Thu, 24 Sep 2026 15:28:51 +0200 Subject: [PATCH 1/7] Test that RPCInvalidArgsException gives a 400 without the etr debug flag --- .../lib/webservicetest.whlib | 1 + .../wh/webserver/remoting/test_jsonrpc.whscr | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/whtree/modules/webhare_testsuite/lib/webservicetest.whlib b/whtree/modules/webhare_testsuite/lib/webservicetest.whlib index c3e207cfee..a5d4d2d4ac 100644 --- a/whtree/modules/webhare_testsuite/lib/webservicetest.whlib +++ b/whtree/modules/webhare_testsuite/lib/webservicetest.whlib @@ -103,6 +103,7 @@ PUBLIC RECORD FUNCTION RPC_CrashTest(STRING type) { CASE "abort" { ABORT("boem"); } CASE "throw" { THROW NEW Exception("boem"); } + CASE "invalidargs" { THROW NEW RPCInvalidArgsException("boem"); } CASE "terminate" { TerminateScript(); } } ABORT("Unknown abort type '" || type || "'"); diff --git a/whtree/modules/webhare_testsuite/tests/wh/webserver/remoting/test_jsonrpc.whscr b/whtree/modules/webhare_testsuite/tests/wh/webserver/remoting/test_jsonrpc.whscr index b03540ff66..9454121eb8 100644 --- a/whtree/modules/webhare_testsuite/tests/wh/webserver/remoting/test_jsonrpc.whscr +++ b/whtree/modules/webhare_testsuite/tests/wh/webserver/remoting/test_jsonrpc.whscr @@ -1,6 +1,7 @@ browser->GetHTTPStatusCode()); } +MACRO TestInvalidArgs() +{ + RECORD port := testfw->GetLocalhostWebinterface(); + STRING url := "http://127.0.0.1:" || port.portnumber || "/wh_services/webhare_testsuite/testnoauth"; + BLOB request := StringToBlob(EncodeJSON([method:="crashtest", params:=["invalidargs"], id:=5])); + RECORD ARRAY headers := + [ [ field := "Content-Type", value := "application/json" ] + ]; + + //testfw->browser has the 'etr' debug flag set. The trace should still be hidden + TestEq(FALSE, testfw->browser->PostWebPageBlob(url, headers, request)); + TestEq(400, testfw->browser->GetHTTPStatusCode()); + TestEq(FALSE, RecordExists(DecodeJSONBlob(testfw->browser->content).error.data)); + + //A browser without the 'etr' debug flag should get a 400 too + OBJECT browser := NEW WebBrowser; + TestEq(FALSE, browser->PostWebPageBlob(url, headers, request)); + TestEq(400, browser->GetHTTPStatusCode()); + browser->Close(); +} + MACRO TestJSONRPC() { RECORD port := testfw->GetLocalhostWebinterface(); @@ -166,6 +188,7 @@ MACRO TestOrigin() } RunTestFramework([ PTR TestBadRequest + , PTR TestInvalidArgs , PTR TestJSONRPC , PTR TestOrigin , PTR TestJSONRPC_JS From d3a7dad4676c90ad608d480a22972c83966738df Mon Sep 17 00:00:00 2001 From: Wouter Hendriks Date: Thu, 24 Sep 2026 15:28:51 +0200 Subject: [PATCH 2/7] Fix JSON-RPC RPCInvalidArgsException crashing the transport without etr Without the etr debug flag the error record has no 'data' cell, so hiding the trace failed with "Column 'DATA' does not exist" and the request became a 500. Fixes #11 --- whtree/modules/system/lib/internal/remoting/transports.whlib | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/whtree/modules/system/lib/internal/remoting/transports.whlib b/whtree/modules/system/lib/internal/remoting/transports.whlib index 6413ff51fb..540747672e 100644 --- a/whtree/modules/system/lib/internal/remoting/transports.whlib +++ b/whtree/modules/system/lib/internal/remoting/transports.whlib @@ -126,7 +126,8 @@ STATIC OBJECTTYPE JSONRPCTransport EXTEND Transport IF(e EXTENDSFROM RPCInvalidArgsException) { httpstatus := 400; - error.data := DEFAULT RECORD; // Hide trace, this is a normal error + IF(CellExists(error, "data")) + error.data := DEFAULT RECORD; // Hide trace, this is a normal error } RECORD responsedata := [ id := requesttoken.id From 680727e4d4f8abbbb860bf5cacdc5b5e1389977e Mon Sep 17 00:00:00 2001 From: Arnold Hendriks Date: Thu, 24 Sep 2026 14:12:12 +0200 Subject: [PATCH 3/7] Move emsdk out of /opt/wh --- .gitignore | 1 - .gitmodules | 3 -- addons/docker-build/Dockerfile | 10 +++--- addons/docker-build/build-functions.sh | 1 - addons/docker-build/builddocker.sh | 12 ++++++-- addons/docker-build/run-devcontainer.sh | 2 ++ addons/docker-build/setup-base-shared.sh | 1 + addons/docker-build/setup-builder.sh | 24 +-------------- addons/docker-build/setup-emsdk.sh | 36 ++++++++++++++++++++++ builder/base_makefile | 2 +- builder/make.sh | 39 +++++++++++++----------- doc/from-source.md | 15 +++++++-- vendor/emsdk | 1 - 13 files changed, 91 insertions(+), 56 deletions(-) delete mode 100644 addons/docker-build/build-functions.sh create mode 100755 addons/docker-build/setup-emsdk.sh delete mode 160000 vendor/emsdk diff --git a/.gitignore b/.gitignore index 4afd407cc4..49bc194c59 100644 --- a/.gitignore +++ b/.gitignore @@ -25,7 +25,6 @@ /whtree/modules/platform/generated/ /vendor/.*.lock -/vendor/wh-current-emscripten-version # We ignore .vscode as c_cpp_properties.json, launch.json and tasks.json aren't standardized (yet) accross developers /.vscode/* diff --git a/.gitmodules b/.gitmodules index 1a5934d74b..93f56e225c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "vendor/libxml2"] path = vendor/libxml2 url = https://github.com/GNOME/libxml2.git -[submodule "vendor/emsdk"] - path = vendor/emsdk - url = https://github.com/emscripten-core/emsdk.git [submodule "whtree/modules/platform/js/certbot/vendor/acme"] path = whtree/modules/platform/js/certbot/vendor/acme url = https://github.com/WebHare/acme.git diff --git a/addons/docker-build/Dockerfile b/addons/docker-build/Dockerfile index a4e3e267bb..6372d060fb 100644 --- a/addons/docker-build/Dockerfile +++ b/addons/docker-build/Dockerfile @@ -43,12 +43,13 @@ ENV \ WEBHARE_CHECKEDOUT_TO=/opt/wh \ WHBUILD_EMSCRIPTEN_VERSION=$WHBUILD_EMSCRIPTEN_VERSION -# Add vendor stuff (needed for emsdk) +# Add vendor stuff (use to be for emsdk, but we still seem to need it?) COPY vendor/ /opt/wh/vendor/ # Base image setup RUN --mount=type=bind,source=addons/docker-build/setup-base-shared.sh,target=/setup-base-shared.sh \ --mount=type=bind,source=addons/docker-build/setup-builder.sh,target=/setup-builder.sh \ + --mount=type=bind,source=addons/docker-build/setup-emsdk.sh,target=/setup-emsdk.sh \ --mount=type=cache,id=builderdownloads,target=/tmp/downloads \ --mount=type=cache,id=baseimage3,sharing=locked,target=/var/cache/dnf \ /bin/bash /setup-builder.sh # 2024-08-19 @@ -75,7 +76,7 @@ RUN --mount=type=bind,source=/ap,target=/mnt/ap \ RUN --mount=type=tmpfs,target=/opt/whbuild \ --mount=type=tmpfs,target=/tmp \ --mount=type=cache,id=compile,target=/tmp/compile \ - /bin/bash -c ". /opt/wh/vendor/emsdk/emsdk_env.sh && /opt/wh/builder/make.sh install" + /opt/wh/builder/make.sh install ################# STAGE devcontainer @@ -97,14 +98,15 @@ ENV \ # Expose usual WebHare hostingports EXPOSE 13684 -# emscripten, pdfbox and tika installed by makefile (because they write to /opt/wh) +# pdfbox and tika installed by makefile (because they write to /opt/wh) # Base image setup RUN --mount=type=bind,source=addons/docker-build/setup-base-shared.sh,target=/setup-base-shared.sh \ --mount=type=bind,source=addons/docker-build/setup-builder.sh,target=/setup-builder.sh \ + --mount=type=bind,source=addons/docker-build/setup-emsdk.sh,target=/setup-emsdk.sh \ --mount=type=cache,id=builderdownloads,target=/tmp/downloads \ --mount=type=cache,id=baseimage3,sharing=locked,target=/var/cache/dnf \ - /bin/bash /setup-builder.sh --skip-emscripten # 2024-08-19 + /bin/bash /setup-builder.sh # 2024-08-19 ARG WHBUILD_ASSETROOT diff --git a/addons/docker-build/build-functions.sh b/addons/docker-build/build-functions.sh deleted file mode 100644 index a9bf588e2f..0000000000 --- a/addons/docker-build/build-functions.sh +++ /dev/null @@ -1 +0,0 @@ -#!/bin/bash diff --git a/addons/docker-build/builddocker.sh b/addons/docker-build/builddocker.sh index c6836c5a8c..8a71f31912 100755 --- a/addons/docker-build/builddocker.sh +++ b/addons/docker-build/builddocker.sh @@ -86,6 +86,14 @@ get_finaltag "${FINALTAGARGS[@]}" list_finaltag if [ -n "$USEPODMAN" ]; then + if ! hash -r podman 2>/dev/null; then + if [ "$WEBHARE_IN_CONTAINER" == "1" ]; then + dnf install -y podman fuse-overlayfs + else + die "Podman not installed on host" + fi + fi + podman -v buildah -v 2>/dev/null || echo "buildah not installed on host" DOCKERBUILDARGS+=(--layers) @@ -112,8 +120,8 @@ fi echo "" echo "Packaging source tree for the WebHare runner" -# Prune empty directories -find "$WEBHARE_CHECKEDOUT_TO" -type d -empty -delete +# Prune empty directories in whtree. The rest is only used in the builder image so not relevant +find "$WEBHARE_CHECKEDOUT_TO"/whtree -type d -empty -delete || true if [ -z "$NOPULL" ]; then DOCKERBUILDARGS+=(--pull) diff --git a/addons/docker-build/run-devcontainer.sh b/addons/docker-build/run-devcontainer.sh index 76dd7ff7df..eb23519f23 100755 --- a/addons/docker-build/run-devcontainer.sh +++ b/addons/docker-build/run-devcontainer.sh @@ -9,4 +9,6 @@ podman run \ --privileged \ -ti \ -v "$(pwd)/../..":/opt/wh \ + -v "devcontainer-currentinstall":/opt/wh/whtree/currentinstall \ + -v "devcontainer-node_modules":/opt/wh/whtree/node_modules \ localhost/webhare/platform:devcontainer diff --git a/addons/docker-build/setup-base-shared.sh b/addons/docker-build/setup-base-shared.sh index bd3749bd7b..c538880233 100644 --- a/addons/docker-build/setup-base-shared.sh +++ b/addons/docker-build/setup-base-shared.sh @@ -1,5 +1,6 @@ # shellcheck shell=bash +######################################## POSTGRES # postgres key & repository - https://www.postgresql.org/download/linux/redhat/ dnf install -y "https://download.postgresql.org/pub/repos/yum/reporpms/EL-10-$(uname -m)/pgdg-redhat-repo-latest.noarch.rpm" diff --git a/addons/docker-build/setup-builder.sh b/addons/docker-build/setup-builder.sh index 0421940c37..7d89281ef2 100755 --- a/addons/docker-build/setup-builder.sh +++ b/addons/docker-build/setup-builder.sh @@ -17,18 +17,6 @@ # Fail on any error set -eo pipefail -SKIP_EMSCRIPTEN= -while [[ $1 =~ ^-.* ]]; do - if [ "$1" == "--skip-emscripten" ]; then - SKIP_EMSCRIPTEN=1 - else - echo "Illegal option $1" - exit 1 - fi - shift -done - - if [ -z "$WHBUILD_DOWNLOADCACHE" ]; then echo WHBUILD_DOWNLOADCACHE not set exit 1 @@ -77,14 +65,4 @@ PACKAGES=( dnf install -y "${PACKAGES[@]}" source "${BASH_SOURCE%/*}/setup-base-shared.sh" - -if [ -z "$SKIP_EMSCRIPTEN" ]; then - if [ -z "$WHBUILD_EMSCRIPTEN_VERSION" ]; then - echo "WHBUILD_EMSCRIPTEN_VERSION not set" - exit 1; - fi - - /opt/wh/vendor/emsdk/emsdk install "$WHBUILD_EMSCRIPTEN_VERSION" - /opt/wh/vendor/emsdk/emsdk activate "$WHBUILD_EMSCRIPTEN_VERSION" - echo "$WHBUILD_EMSCRIPTEN_VERSION" > /opt/wh/vendor/wh-current-emscripten-version -fi +"${BASH_SOURCE%/*}/setup-emsdk.sh" diff --git a/addons/docker-build/setup-emsdk.sh b/addons/docker-build/setup-emsdk.sh new file mode 100755 index 0000000000..39a9dce252 --- /dev/null +++ b/addons/docker-build/setup-emsdk.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -eo pipefail + +if [ -z "$WHBUILD_EMSCRIPTEN_VERSION" ]; then + echo "WHBUILD_EMSCRIPTEN_VERSION not set" + exit 1; +fi +if [ -z "$WEBHARE_BUILDDIR" ]; then + echo "WEBHARE_BUILDDIR not set" + exit 1 +fi + +if [ "$WEBHARE_IN_CONTAINER" == "1" ]; then + WHBUILD_EMSDK_ROOT="/opt/emsdk" +else + WHBUILD_EMSDK_ROOT="$WEBHARE_BUILDDIR/emsdk" +fi + +VERSIONFILE="$WHBUILD_EMSDK_ROOT/current-emscripten-version" + +if [ "$WHBUILD_EMSCRIPTEN_VERSION" != "$(cat "$VERSIONFILE" 2> /dev/null || true)" ]; then + # maybe toplevel should set a WHBUILD_VENDORDIR, poiting to BUILDDIR on Mac but /opt/ in containers + + if [ -d "$WHBUILD_EMSDK_ROOT/.git" ]; then + git -C "$WHBUILD_EMSDK_ROOT" pull + else + git clone https://github.com/emscripten-core/emsdk.git "$WHBUILD_EMSDK_ROOT" + fi + + cd "$WHBUILD_EMSDK_ROOT" + + "$WHBUILD_EMSDK_ROOT/emsdk" install "$WHBUILD_EMSCRIPTEN_VERSION" + "$WHBUILD_EMSDK_ROOT/emsdk" activate "$WHBUILD_EMSCRIPTEN_VERSION" + + echo "$WHBUILD_EMSCRIPTEN_VERSION" > "$VERSIONFILE" +fi diff --git a/builder/base_makefile b/builder/base_makefile index 2aa3d03563..996cd2952a 100644 --- a/builder/base_makefile +++ b/builder/base_makefile @@ -212,7 +212,7 @@ DRAWLIB_STATIC_LIBS= DRAWLIB_BASE_LIBS+=jpeg EMCC?=emcc -EMSCRIPTEN_VERSION_FILE := $(SRCDIR)/vendor/wh-current-emscripten-version +EMSCRIPTEN_VERSION_FILE := $(WHBUILD_EMSDK_ROOT)/current-emscripten-version ifeq ($(BUILDSYSTEM),gcc) ifeq ($(CXX),clang++) diff --git a/builder/make.sh b/builder/make.sh index 5de5b66bcb..ce38252aee 100755 --- a/builder/make.sh +++ b/builder/make.sh @@ -142,28 +142,33 @@ if [ -z "$WEBHARE_IN_DOCKER" ] || [ -n "$WHBUILD_DEVCONTAINER" ]; then # Not a d if ! /bin/bash "$WEBHARE_CHECKEDOUT_TO/addons/docker-build/setup-tika.sh" "$WHBUILD_ASSETROOT" 3.3.0; then echo "setup-tika failed" fi - rm -rf "$WEBHARE_CHECKEDOUT_TO/whtree/modules/system/data/engines" fi -# Is emsdk installed? -if [ -z "$WEBHARE_IN_DOCKER" ] || [ -n "$WHBUILD_DEVCONTAINER" ]; then - [ -x "$WEBHARE_CHECKEDOUT_TO/vendor/emsdk/emsdk" ] || git -C "$WEBHARE_CHECKEDOUT_TO" submodule update --init --recursive - [ -x "$WEBHARE_CHECKEDOUT_TO/vendor/emsdk/emsdk" ] || die "Submodule vendor/emsdk not present" - # TODO skip if already activated. need to support version checks then - # TODO can we ensure wasm-clean is invoked (ideally set a proper dep) whenever emsdk is updated? - - if [ "$WHBUILD_EMSCRIPTEN_VERSION" != "$(cat "$WEBHARE_CHECKEDOUT_TO/vendor/wh-current-emscripten-version" 2> /dev/null)" ]; then - "$WEBHARE_CHECKEDOUT_TO/vendor/emsdk/emsdk" install "$WHBUILD_EMSCRIPTEN_VERSION" - "$WEBHARE_CHECKEDOUT_TO/vendor/emsdk/emsdk" activate "$WHBUILD_EMSCRIPTEN_VERSION" - echo "$WHBUILD_EMSCRIPTEN_VERSION" > "$WEBHARE_CHECKEDOUT_TO/vendor/wh-current-emscripten-version" - fi +# Remove old version file (2026-09-24) +if [ -f "$WEBHARE_CHECKEDOUT_TO/vendor/wh-current-emscripten-version" ]; then + rm "$WEBHARE_CHECKEDOUT_TO/vendor/wh-current-emscripten-version" + rm -rf "$WEBHARE_CHECKEDOUT_TO/vendor/emsdk" +fi - if [ -z "$DEBUGMAKE" ] && [ -z "$EMSDK_QUIET" ]; then - export EMSDK_QUIET=1 - fi - source "$WEBHARE_CHECKEDOUT_TO/vendor/emsdk/emsdk_env.sh" +# ============ emsdk installation & configuration ===================== +# TODO can we ensure wasm-clean is invoked (ideally set a proper dep) whenever emsdk is updated? +# let emsdk check versions and upgrade if needed. note that addons/ is not present in the build steps of +[ -f "$WEBHARE_CHECKEDOUT_TO"/addons/docker-build/setup-emsdk.sh ] && "$WEBHARE_CHECKEDOUT_TO"/addons/docker-build/setup-emsdk.sh + +if [ -z "$DEBUGMAKE" ] && [ -z "$EMSDK_QUIET" ]; then + export EMSDK_QUIET=1 fi +if [ "$WEBHARE_IN_CONTAINER" == "1" ]; then + WHBUILD_EMSDK_ROOT="/opt/emsdk" +else + WHBUILD_EMSDK_ROOT="$WEBHARE_BUILDDIR/emsdk" +fi +export WHBUILD_EMSDK_ROOT + +# shellcheck disable=SC1091 +source "$WHBUILD_EMSDK_ROOT/emsdk_env.sh" + # Convert version number to 5 digit style used in C++/HareScript (GetWebHareVersionNumber) if [[ $WEBHARE_VERSION =~ ^([0-9]{1})\.([0-9]{1,2})\.([0-9]{1,2})$ ]]; then VERSIONMAJOR="${BASH_REMATCH[1]}" diff --git a/doc/from-source.md b/doc/from-source.md index 38b8075dca..d1b5cc6fdd 100644 --- a/doc/from-source.md +++ b/doc/from-source.md @@ -69,12 +69,21 @@ If you're getting an error that openjdk isn't notarized, you can go to System Pr "Allow anyway" on the General tab to enable it. ## Build using devcontainer & podman +The devcontainer can be used to build WebHare container images + ```bash -wh builddocker --podman --devcontainer -podman run --rm -ti -v ~/projects/webhare:/opt/wh --device /dev/fuse --net host --privileged localhost/webhare/platform:developcontainer /bin/bash -wh builddocker --podman +addons/docker-build/build-devcontainer.sh +addons/docker-build/run-devcontainer.sh +wh builddocker --podman --build-arg --net=host ``` +or to build WebHare from source + +```bash +addons/docker-build/build-devcontainer.sh +addons/docker-build/run-devcontainer.sh +wh make install +``` ## Building for docker ```bash diff --git a/vendor/emsdk b/vendor/emsdk deleted file mode 160000 index 15915cad55..0000000000 --- a/vendor/emsdk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 15915cad554b707837024dc2758b6a1c5b94b036 From 96e3b0585852976877e9e6e34490eeeae8fdb38c Mon Sep 17 00:00:00 2001 From: Kris Breuker Date: Thu, 24 Sep 2026 18:07:41 +0200 Subject: [PATCH 4/7] Add some WHFS index debugging info --- whtree/modules/consilio/lib/whfscatalog.whlib | 2 ++ whtree/modules/publisher/scripts/internal/consiliohandler.whscr | 2 ++ 2 files changed, 4 insertions(+) diff --git a/whtree/modules/consilio/lib/whfscatalog.whlib b/whtree/modules/consilio/lib/whfscatalog.whlib index 0d6ce3dc28..5b9e2fe5f0 100644 --- a/whtree/modules/consilio/lib/whfscatalog.whlib +++ b/whtree/modules/consilio/lib/whfscatalog.whlib @@ -78,6 +78,8 @@ PUBLIC MACRO ReindexWHFSChanges(RECORD ARRAY to_reindex, RECORD options DEFAULTS IF (options.__debug) Print(`To update: ${EncodeJSON(to_update)}\nTo delete: ${EncodeJSON(to_delete)}\n`); + IF (IsDebugTagEnabled("consilio:whfscatalog")) + LogDebug("consilio:whfscatalog", "ReindexWHFSChanges", CELL[ to_update, to_delete ]); DATETIME now := GetCurrentDateTime(); FOREVERY (INTEGER objid FROM to_delete) diff --git a/whtree/modules/publisher/scripts/internal/consiliohandler.whscr b/whtree/modules/publisher/scripts/internal/consiliohandler.whscr index 0da684e715..79e132a1f2 100644 --- a/whtree/modules/publisher/scripts/internal/consiliohandler.whscr +++ b/whtree/modules/publisher/scripts/internal/consiliohandler.whscr @@ -103,6 +103,8 @@ MACRO OnFolderEvent(STRING event, RECORD ARRAY messages) MACRO OnIndexRequest(STRING event, RECORD ARRAY msgs) { + IF (IsDebugTagEnabled("consilio:whfscatalog")) + LogDebug("consilio:whfscatalog", "OnIndexRequest", CELL[ event, msgs ]); PrintDebug("Got index request '" || event || "'"); EnsurePublisherWHFSIndex(); From 348b7b443f50df0386c66898f7a5b78705b6d6ac Mon Sep 17 00:00:00 2001 From: Kris Breuker Date: Fri, 25 Sep 2026 12:42:48 +0200 Subject: [PATCH 5/7] Catch and log WHFS indexing errors --- whtree/modules/consilio/lib/whfscatalog.whlib | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/whtree/modules/consilio/lib/whfscatalog.whlib b/whtree/modules/consilio/lib/whfscatalog.whlib index 5b9e2fe5f0..daef093651 100644 --- a/whtree/modules/consilio/lib/whfscatalog.whlib +++ b/whtree/modules/consilio/lib/whfscatalog.whlib @@ -11,6 +11,7 @@ LOADLIB "wh::util/algorithms.whlib"; LOADLIB "mod::consilio/lib/api.whlib"; LOADLIB "mod::consilio/lib/catalogs.whlib"; +LOADLIB "mod::system/lib/services.whlib"; LOADLIB "mod::system/lib/internal/webhareconstants.whlib"; @@ -34,7 +35,6 @@ INTEGER ARRAY FUNCTION GetIndexedWHFSObjectsForFolder(INTEGER folderid) */ PUBLIC MACRO ReindexWHFSChanges(RECORD ARRAY to_reindex, RECORD options DEFAULTSTO DEFAULT RECORD) { - RECORD ARRAY results; options := ValidateOptions([ __eventid := "", __debug := FALSE, __progress := FALSE, refresh := TRUE ], options); IF(NOT ObjectExists(publisher_fsobjects_source)) @@ -84,7 +84,10 @@ PUBLIC MACRO ReindexWHFSChanges(RECORD ARRAY to_reindex, RECORD options DEFAULTS DATETIME now := GetCurrentDateTime(); FOREVERY (INTEGER objid FROM to_delete) { - publisher_fsobjects_source->DeleteGroup("fsobj_" || objid, [ foreground := TRUE ]); + TRY + publisher_fsobjects_source->DeleteGroup("fsobj_" || objid, [ foreground := TRUE ]); + CATCH (OBJECT e) + LogHareScriptException(e, [ info := [ context := "consilio:whfscatalog", to_delete := objid ] ]); IF(options.__progress) Print(`Deleting ${#objid+1}/${Length(to_delete)}: #${objid}\r`); } @@ -93,15 +96,14 @@ PUBLIC MACRO ReindexWHFSChanges(RECORD ARRAY to_reindex, RECORD options DEFAULTS FOREVERY (INTEGER objid FROM to_update) { - publisher_fsobjects_source->ReindexGroup("fsobj_" || objid, [ foreground := TRUE ]); + TRY + publisher_fsobjects_source->ReindexGroup("fsobj_" || objid, [ foreground := TRUE ]); + CATCH (OBJECT e) + LogHareScriptException(e, [ info := [ context := "consilio:whfscatalog", to_update := objid ] ]); IF(options.__progress) Print(`Updating ${#objid+1}/${Length(to_update)}: #${objid}\r`); } - // Sort the results: first the requested ids in the order they're supplied, then other ids sorted ascending - INTEGER ARRAY orgids := SELECT AS INTEGER ARRAY id FROM to_reindex; - results := SELECT * FROM results ORDER BY SearchElement(orgids, objid) + 1 ?? objid; - IF(options.__progress AND Length(to_update) > 0) Print(`\n`); From b31eedaf6cde6956b4ef31f29cd755caec92ede0 Mon Sep 17 00:00:00 2001 From: Arnold Hendriks Date: Fri, 25 Sep 2026 13:21:47 +0200 Subject: [PATCH 6/7] Fix exceptions breaking event callback serializer (cherry picked from commit caf43a0741c7954c4eb178d174d2f93db1c60565) Co-authored-by: Rob Hulswit --- .../lib/internal/cluster/logwriter.whlib | 1 - .../system/whlibs/internal/callbacks.whlib | 4 ++++ .../tests/baselibs/hsengine/test_ipc.whscr | 21 +++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/whtree/modules/system/lib/internal/cluster/logwriter.whlib b/whtree/modules/system/lib/internal/cluster/logwriter.whlib index 458ccfb38f..29ea82dec1 100644 --- a/whtree/modules/system/lib/internal/cluster/logwriter.whlib +++ b/whtree/modules/system/lib/internal/cluster/logwriter.whlib @@ -1,7 +1,6 @@ reg.asynccontext) this->reg.callback(rec.event, rec.msgs); + CATCH (OBJECT e) + LogNoticeException("script-error", "", e, DEFAULT RECORD); FINALLY __internal_forbidden_broadcasts := oldlist; } diff --git a/whtree/modules/webhare_testsuite/tests/baselibs/hsengine/test_ipc.whscr b/whtree/modules/webhare_testsuite/tests/baselibs/hsengine/test_ipc.whscr index a50f62f98f..7ef4398c9a 100644 --- a/whtree/modules/webhare_testsuite/tests/baselibs/hsengine/test_ipc.whscr +++ b/whtree/modules/webhare_testsuite/tests/baselibs/hsengine/test_ipc.whscr @@ -140,6 +140,9 @@ MACRO OnEventCallbackS(STRING event, RECORD data) MACRO OnEventCallbackM(STRING event, RECORD ARRAY data) { INSERT [ type := "event-multiple", event := event, data := data ] INTO cbs AT END; + FOREVERY (RECORD rec FROM data) + IF (CellExists(rec, "EXC")) + THROW NEW Exception(rec.exc); } MACRO OnHandleCallback(INTEGER handle, OBJECT port) @@ -230,6 +233,24 @@ MACRO CallbackTest() UnregisterCallback(cbhandle); DoCallbackHandling(AddTimeToDate(250, GetCurrentDateTime())); TestEQ(DEFAULT RECORD ARRAY, cbs); + + // STORY: exception broke callback handler + cbhandle := RegisterMultiEventCallback("hs:test", PTR OnEventCallbackM); + RawBroadcastEvent("hs:test", [ a := 1 ]); + DoCallbackHandling(AddTimeToDate(250, GetCurrentDateTime())); + RawBroadcastEvent("hs:test", [ exc := "test exception" ]); + DoCallbackHandling(AddTimeToDate(250, GetCurrentDateTime())); + TestEQ([ [ type := "event-multiple", event := "hs:test", data := [ [ a := 1] ] ] + , [ type := "event-multiple", event := "hs:test", data := [ [ exc := "test exception" ] ] ] + ], cbs); + RawBroadcastEvent("hs:test", [ a := 2 ]); + DoCallbackHandling(AddTimeToDate(250, GetCurrentDateTime())); + TestEQ([ [ type := "event-multiple", event := "hs:test", data := [ [ a := 1] ] ] + , [ type := "event-multiple", event := "hs:test", data := [ [ exc := "test exception" ] ] ] + , [ type := "event-multiple", event := "hs:test", data := [ [ a := 2] ] ] + ], cbs); + UnregisterCallback(cbhandle); + cbs := DEFAULT RECORD ARRAY; } MACRO ImmediateBroadcastCallbackTest() From 411215a8326224b6bb018b93f9b32fca4238ab4e Mon Sep 17 00:00:00 2001 From: Arnold Hendriks Date: Fri, 25 Sep 2026 09:56:56 +0200 Subject: [PATCH 7/7] verify the buildscripts --- .github/workflows/ci.yml | 4 ++ .github/workflows/devcontainer.yml | 40 +++++++++++++++++++ addons/docker-build/run-devcontainer.sh | 5 ++- addons/tests/test-devcontainer-builddocker.sh | 6 +++ .../tests/test-devcontainer-make-install.sh | 6 +++ 5 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/devcontainer.yml create mode 100755 addons/tests/test-devcontainer-builddocker.sh create mode 100755 addons/tests/test-devcontainer-make-install.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb0de95457..5b8341303b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,10 @@ on: - cron: "0 3 * * 0" workflow_dispatch: +concurrency: # cancel older workflows when a new push is done on a branch + group: \({{ github.workflow }}-\){{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + env: CI_REGISTRY_IMAGE: ghcr.io/webhare/platform CI_COMMIT_SHA: ${{ github.sha }} diff --git a/.github/workflows/devcontainer.yml b/.github/workflows/devcontainer.yml new file mode 100644 index 0000000000..727215b6bd --- /dev/null +++ b/.github/workflows/devcontainer.yml @@ -0,0 +1,40 @@ +name: WebHare Devcontainer + +on: + schedule: + - cron: "0 4 * * 1-5" + workflow_dispatch: #Note that this won't work until the default branch has devcontainer.yml + push: + branches: #Use feature/devcontainer- branches for development + - feature/devcontainer-* + +concurrency: # cancel older workflows when a new push is done on a branch + group: \({{ github.workflow }}-\){{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + builddocker: + name: Build Docker + # See https://github.com/actions/runner-images + runs-on: ubuntu-26.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Build Docker in devcontainer + run: addons/tests/test-devcontainer-builddocker.sh + + make-install: + name: Make install + # See https://github.com/actions/runner-images + runs-on: ubuntu-26.04 + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + - name: Run make install in devcontainer + run: addons/tests/test-devcontainer-make-install.sh diff --git a/addons/docker-build/run-devcontainer.sh b/addons/docker-build/run-devcontainer.sh index eb23519f23..b335608fed 100755 --- a/addons/docker-build/run-devcontainer.sh +++ b/addons/docker-build/run-devcontainer.sh @@ -4,6 +4,8 @@ set -euo pipefail cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1 +# To reduce interference when sharing a wh tree, isolate currentinstall (multiple WHs will write to it) and isolate node_modules (mac&linux require different binaries) + podman run \ --rm \ --privileged \ @@ -11,4 +13,5 @@ podman run \ -v "$(pwd)/../..":/opt/wh \ -v "devcontainer-currentinstall":/opt/wh/whtree/currentinstall \ -v "devcontainer-node_modules":/opt/wh/whtree/node_modules \ - localhost/webhare/platform:devcontainer + localhost/webhare/platform:devcontainer \ + "$@" diff --git a/addons/tests/test-devcontainer-builddocker.sh b/addons/tests/test-devcontainer-builddocker.sh new file mode 100755 index 0000000000..6a6aeb9c95 --- /dev/null +++ b/addons/tests/test-devcontainer-builddocker.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -euo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")"/../.. || exit 1 + +addons/docker-build/build-devcontainer.sh +addons/docker-build/run-devcontainer.sh wh builddocker --podman --build-arg --net=host diff --git a/addons/tests/test-devcontainer-make-install.sh b/addons/tests/test-devcontainer-make-install.sh new file mode 100755 index 0000000000..8bcfe6a874 --- /dev/null +++ b/addons/tests/test-devcontainer-make-install.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -euo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")"/../.. || exit 1 + +addons/docker-build/build-devcontainer.sh +addons/docker-build/run-devcontainer.sh wh make install