Skip to content
This repository was archived by the owner on Sep 11, 2025. It is now read-only.

Commit cf3669e

Browse files
committed
tests: add basic example of exception handling working in Modus
1 parent c4dc40e commit cf3669e

File tree

12 files changed

+2054
-0
lines changed

12 files changed

+2054
-0
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.modusdb/
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"plugins": ["assemblyscript-prettier"]
3+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Modus Exception Handling Example
2+
3+
This example shows how to catch exceptions with `try/catch/finally` using [JairusSW/try-as](https://github.com/JairusSW/try-as)
4+
5+
See [./assembly/index.ts](./assembly/index.ts) for the implementation.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": "./node_modules/@hypermode/modus-sdk-as/plugin.asconfig.json",
3+
"options": {
4+
"transform": ["@hypermode/modus-sdk-as/transform", "json-as/transform","try-as/transform"]
5+
}
6+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* This example is part of the Modus project, licensed under the Apache License 2.0.
3+
* You may modify and use this example in accordance with the license.
4+
* See the LICENSE file that accompanied this code for further details.
5+
*/
6+
7+
// These classes are used by the example functions in the index.ts file.
8+
9+
@json
10+
export class Quote {
11+
12+
@alias("q")
13+
quote: string | null = null;
14+
15+
16+
@alias("a")
17+
author: string | null = null;
18+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import {
2+
Exception as __Exception,
3+
ExceptionState as __ExceptionState
4+
} from "try-as/assembly/types/exception";
5+
import {
6+
ErrorState as __ErrorState
7+
} from "try-as/assembly/types/error";
8+
import {
9+
UnreachableState as __UnreachableState
10+
} from "try-as/assembly/types/unreachable";
11+
import {
12+
AbortState as __AbortState
13+
} from "try-as/assembly/types/abort";
14+
import {
15+
http
16+
} from "@hypermode/modus-sdk-as";
17+
import {
18+
Quote
19+
} from "./classes";
20+
import {
21+
Exception
22+
} from "try-as";
23+
export function __try_getRandomQuote(): Quote {
24+
if (__ExceptionState.Failures > 0) {
25+
if (isBoolean<Quote>()) return false;
26+
else if (isInteger<Quote>() || isFloat<Quote>()) return 0;
27+
else if (isManaged<Quote>() || isReference<Quote>()) return changetype<Quote>(0);
28+
else return;
29+
}
30+
const request = new http.Request("https://zenquotes.io/api/random");
31+
const response = http.fetch(request);
32+
if (!response.ok) {
33+
__ErrorState.error(new Error(`Failed to fetch quote. Received: ${response.status} ${response.statusText}`), "assembly/index.ts", 16, 5);
34+
if (isBoolean<Quote>()) return false;
35+
else if (isInteger<Quote>() || isFloat<Quote>()) return 0;
36+
else if (isManaged<Quote>() || isReference<Quote>()) return changetype<Quote>(0);
37+
else return;
38+
}
39+
return response.json<Array<Quote>>()[0];
40+
}
41+
export function getRandomQuote(): Quote {
42+
const request = new http.Request("https://zenquotes.io/api/random");
43+
const response = http.fetch(request);
44+
if (!response.ok) {
45+
throw new Error(`Failed to fetch quote. Received: ${response.status} ${response.statusText}`);
46+
}
47+
return response.json<Array<Quote>>()[0];
48+
}
49+
export function safeFetchQuote(): Quote {
50+
do {
51+
return __try_getRandomQuote();
52+
} while (false);
53+
if (__ExceptionState.Failures > 0) {
54+
let e = new __Exception(__ExceptionState.Type);
55+
__ExceptionState.Failures--;
56+
return {
57+
author: "Unknown",
58+
quote: "Failed to fetch quote"
59+
}
60+
}
61+
}
62+
export function testCatching(shouldThrow: boolean): string {
63+
do {
64+
if (shouldThrow) {
65+
__ErrorState.error(new Error("Test error"), "assembly/index.ts", 38, 7);
66+
break;
67+
}
68+
return "Success";
69+
} while (false);
70+
if (__ExceptionState.Failures > 0) {
71+
let e = new __Exception(__ExceptionState.Type);
72+
__ExceptionState.Failures--;
73+
const err = e as Exception;
74+
return "Caught error: " + err.toString();
75+
}
76+
return "";
77+
}
78+
export function parseI8OrFallback(s: string, fallback: i8): i8 {
79+
do {
80+
let n = i8.parse(s);
81+
return n;
82+
} while (false);
83+
if (__ExceptionState.Failures > 0) {
84+
let _ = new __Exception(__ExceptionState.Type);
85+
__ExceptionState.Failures--;
86+
return fallback;
87+
}
88+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* This example is part of the Modus project, licensed under the Apache License 2.0.
3+
* You may modify and use this example in accordance with the license.
4+
* See the LICENSE file that accompanied this code for further details.
5+
*/
6+
7+
import { http } from "@hypermode/modus-sdk-as";
8+
import { Quote } from "./classes";
9+
import { Exception } from "try-as";
10+
11+
export function getRandomQuote(): Quote {
12+
const request = new http.Request("https://zenquotes.io/api/random");
13+
14+
const response = http.fetch(request);
15+
if (!response.ok) {
16+
throw new Error(
17+
`Failed to fetch quote. Received: ${response.status} ${response.statusText}`,
18+
);
19+
}
20+
21+
return response.json<Quote[]>()[0];
22+
}
23+
24+
export function safeFetchQuote(): Quote {
25+
try {
26+
return getRandomQuote();
27+
} catch (e) {
28+
return {
29+
author: "Unknown",
30+
quote: "Failed to fetch quote",
31+
};
32+
}
33+
}
34+
35+
export function testCatching(shouldThrow: boolean): string {
36+
try {
37+
if (shouldThrow) {
38+
throw new Error("Test error");
39+
}
40+
return "Success";
41+
} catch (e) {
42+
const err = e as Exception;
43+
return "Caught error: " + err.toString();
44+
}
45+
return "";
46+
}
47+
48+
export function parseI8OrFallback(s: string, fallback: i8): i8 {
49+
try {
50+
let n = i8.parse(s)
51+
return n;
52+
} catch (_) {
53+
return fallback;
54+
}
55+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"extends": "assemblyscript/std/assembly.json",
3+
"include": ["./**/*.ts"]
4+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// @ts-check
2+
3+
import eslint from "@eslint/js";
4+
import tseslint from "typescript-eslint";
5+
import aseslint from "@hypermode/modus-sdk-as/tools/assemblyscript-eslint-local";
6+
7+
export default tseslint.config(
8+
eslint.configs.recommended,
9+
...tseslint.configs.recommended,
10+
aseslint.config,
11+
);
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
{
2+
"$schema": "https://schema.hypermode.com/modus.json",
3+
"endpoints": {
4+
"default": {
5+
"type": "graphql",
6+
"path": "/graphql",
7+
"auth": "bearer-token"
8+
}
9+
},
10+
"connections": {
11+
// These are the hosts used by the functions in this example project.
12+
// Where secrets are required, {{SECRET_NAME}} templates are replaced with
13+
// the values specified in the Hypermode Console.
14+
// Note that "baseUrl" is specified instead of "endpoint", to allow for
15+
// customization of the URL in the function code.
16+
"example": {
17+
"type": "http",
18+
"baseUrl": "https://example.com/"
19+
},
20+
"zenquotes": {
21+
"type": "http",
22+
"baseUrl": "https://zenquotes.io/"
23+
},
24+
"picsum": {
25+
"type": "http",
26+
"baseUrl": "https://picsum.photos/"
27+
},
28+
"github": {
29+
"type": "http",
30+
"baseUrl": "https://api.github.com/",
31+
"headers": {
32+
"Authorization": "Bearer {{AUTH_TOKEN}}"
33+
}
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)