Repository: winglang/wing (TypeScript)

Issue:
Wing test returns 0 exit code
### Feature Spec

Wing test command should have appropriate exit codes based on the outcome of the command. Test failures have a non zero exit code, as well as a compilation failure. Right now everything exits with a 0 exit code.

### Use Cases

CI, developer experience

### Implementation Notes

_No response_

### Component

CLI

### Community Notes

<!-- Please keep this note for the community -->
* Please vote by adding a 👍 reaction to the issue to help us prioritize.
* If you are interested to work on this issue, please leave a comment.



Discussion: `wing test` always exiting with 0 is definitely a bug! Thanks for bringing to our attention @eladcon 
Just noticed this as well :) https://github.com/winglang/examples/actions/runs/5399082880/jobs/9805748933?pr=4
Marking as good first issue
Congrats! :rocket: This was released in [Wing 0.23.2](https://github.com/winglang/wing/releases/tag/v0.23.2).



Fix (patch):
diff --git a/apps/wing/src/cli.ts b/apps/wing/src/cli.ts
index 3915272b9cd..86868ebae30 100644
--- a/apps/wing/src/cli.ts
+++ b/apps/wing/src/cli.ts
@@ -14,11 +14,17 @@ if (!SUPPORTED_NODE_VERSION) {
 }
 
 function actionErrorHandler(fn: (...args: any[]) => Promise<any>) {
-  return (...args: any[]) =>
-    fn(...args).catch((err: Error) => {
+  return async (...args: any[]) => {
+    try {
+      const exitCode = await fn(...args);
+      if (exitCode === 1) {
+        process.exit(1);
+      }
+    } catch (err) {
       console.error(err);
       process.exit(1);
-    });
+    }
+  };
 }
 
 async function main() {
diff --git a/tools/hangar/__snapshots__/invalid.ts.snap b/tools/hangar/__snapshots__/invalid.ts.snap
index 1906fb28c40..ed602a6ff14 100644
--- a/tools/hangar/__snapshots__/invalid.ts.snap
+++ b/tools/hangar/__snapshots__/invalid.ts.snap
@@ -659,15 +659,6 @@ Test Files 1 failed (1)
 Duration <DURATION>"
 `;
 
-exports[`inflight_class_capture_mutable.w 1`] = `
-"pass ─ inflight_class_capture_mutable.wsim (no tests)
- 
- 
-Tests 1 passed (1)
-Test Files 1 passed (1)
-Duration <DURATION>"
-`;
-
 exports[`inflight_class_created_in_preflight.w 1`] = `
 "error: Cannot create inflight class \\"Foo\\" in preflight phase
   --> ../../../examples/tests/invalid/inflight_class_created_in_preflight.w:3:1
diff --git a/tools/hangar/src/utils.ts b/tools/hangar/src/utils.ts
index 25e0322ad68..770bb4c2f68 100644
--- a/tools/hangar/src/utils.ts
+++ b/tools/hangar/src/utils.ts
@@ -8,7 +8,7 @@ export interface RunWingCommandOptions {
   cwd: string;
   wingFile: string;
   args: string[];
-  expectStdErr: boolean;
+  expectFailure: boolean;
   plugins?: string[];
   env?: Record<string, string>;
 }
@@ -25,18 +25,13 @@ export async function runWingCommand(options: RunWingCommandOptions) {
       env: options.env,
     }
   );
-  if (options.expectStdErr) {
+
+  if (options.expectFailure) {
     expect(out.exitCode).not.toBe(0);
-    expect(out.stderr).not.toBe("");
   } else {
-    if (
-      // when this env var is on, we allow the on-demand-panic-char (😱), right now panic writes to stderr (will be changed in the future)
-      options?.env?.WINGC_DEBUG_PANIC !== "type-checking" &&
-      (out.exitCode !== 0 || out.stderr !== "")
-    ) {
-      expect.fail(out.stderr);
-    }
+    expect(out.exitCode).toBe(0);
   }
+
   out.stderr = sanitizeOutput(out.stderr);
   out.stdout = sanitizeOutput(out.stdout);
   return out;