#services return ExecErrors

1 messages · Page 1 of 1 (latest)

crimson gate
#

threading for large code snippet

#
func (ServiceSuite) TestStartExecError(ctx context.Context, t *testctx.T) {
    c := connect(ctx, t)

    // Create a service that will fail immediately with a non-zero exit code
    // Use a service that binds to a port but exits immediately to trigger the start path
    // Skip health check so we can see the startup error directly
    failingService := c.Container().
        From(alpineImage).
        WithExposedPort(8080, dagger.ContainerWithExposedPortOpts{
            ExperimentalSkipHealthcheck: true,
        }).
        WithExec([]string{"sh", "-c", "echo 'stdout message'; echo 'stderr message' >&2; exit 42"}).
        AsService()

    // Start the service directly, which should trigger Service.Start and fail
    _, err := failingService.Start(ctx)

    // Verify we get an ExecError
    require.Error(t, err)

    var execErr *dagger.ExecError
    require.True(t, errors.As(err, &execErr), "expected error to be an ExecError, got %T", err)

    // Verify the ExecError contains expected information
    require.Equal(t, 42, execErr.ExitCode)
    require.Contains(t, execErr.Stdout, "stdout message")
    require.Contains(t, execErr.Stderr, "stderr message")
    require.Equal(t, []string{"sh", "-c", "echo 'stdout message'; echo 'stderr message' >&2; exit 42"}, execErr.Cmd)
}
#

(disclaimer: vibe coded)

#

ahhh it's probably because it's failing in the WithExec, this is the old-style of exec services. needs to do AsService with args instead

open monolith
#

yep

    // Start the service
    svc, err := container.AsService(dagger.ContainerAsServiceOpts{
        Args:          args,
        UseEntrypoint: true,
    }).Start(ctx)
#

that's what I'm doing

crimson gate
#

yep fails with that change (AI went with WithDefaultArgs instead, fair enough)

crimson gate
#

services return ExecErrors

open monolith
#

!!!