clawport-ui 0.8.6 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/crons.test.ts CHANGED
@@ -254,18 +254,25 @@ describe('getCrons - error and lastError', () => {
254
254
  })
255
255
  })
256
256
 
257
- // --- Error propagation (current implementation throws) ---
257
+ // --- Graceful degradation (returns empty array on failure) ---
258
258
 
259
- describe('getCrons - error propagation', () => {
260
- it('throws when execSync throws (CLI not installed)', async () => {
259
+ describe('getCrons - graceful degradation', () => {
260
+ it('returns empty array when execSync throws (CLI not installed)', async () => {
261
261
  mockExecSync.mockImplementation(() => { throw new Error('ENOENT') })
262
- await expect(getCrons()).rejects.toThrow('Failed to fetch cron jobs')
263
- await expect(getCrons()).rejects.toThrow('ENOENT')
262
+ const result = await getCrons()
263
+ expect(result).toEqual([])
264
264
  })
265
265
 
266
- it('throws for invalid JSON output', async () => {
266
+ it('returns empty array for invalid JSON output', async () => {
267
267
  mockExecSync.mockReturnValue('not valid json {{')
268
- await expect(getCrons()).rejects.toThrow('Failed to fetch cron jobs')
268
+ const result = await getCrons()
269
+ expect(result).toEqual([])
270
+ })
271
+
272
+ it('returns empty array when OPENCLAW_BIN is not set', async () => {
273
+ vi.unstubAllEnvs()
274
+ const result = await getCrons()
275
+ expect(result).toEqual([])
269
276
  })
270
277
  })
271
278
 
package/lib/crons.ts CHANGED
@@ -32,11 +32,22 @@ export async function getCrons(): Promise<CronJob[]> {
32
32
  }
33
33
 
34
34
  try {
35
- const openclawBin = requireEnv('OPENCLAW_BIN')
36
- const raw = execSync(`${openclawBin} cron list --json`, {
37
- encoding: 'utf-8',
38
- timeout: 10000,
39
- })
35
+ const openclawBin = process.env.OPENCLAW_BIN
36
+ if (!openclawBin) {
37
+ // No binary configured -- return empty list instead of crashing
38
+ return []
39
+ }
40
+
41
+ let raw: string
42
+ try {
43
+ raw = execSync(`${openclawBin} cron list --json`, {
44
+ encoding: 'utf-8',
45
+ timeout: 10000,
46
+ })
47
+ } catch {
48
+ // CLI failed (binary not found, no crons, gateway down) -- return empty
49
+ return []
50
+ }
40
51
 
41
52
  const parsed = extractJson(raw) as Record<string, unknown>
42
53
  const jobs: unknown[] = Array.isArray(parsed)
@@ -113,9 +124,8 @@ export async function getCrons(): Promise<CronJob[]> {
113
124
 
114
125
  _cronsCache = { result, ts: Date.now() }
115
126
  return result
116
- } catch (err) {
117
- throw new Error(
118
- `Failed to fetch cron jobs: ${err instanceof Error ? err.message : String(err)}`
119
- )
127
+ } catch {
128
+ // JSON extraction or parsing failed -- return empty rather than 500
129
+ return []
120
130
  }
121
131
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawport-ui",
3
- "version": "0.8.6",
3
+ "version": "0.8.7",
4
4
  "description": "Open-source dashboard for managing, monitoring, and chatting with your OpenClaw AI agents.",
5
5
  "homepage": "https://clawport.dev",
6
6
  "repository": {