admin/internet/ddns: better error visualization
Massimo Melina committed
Jan 30, 2024 at 15:48 UTC
8ce4db90f977cafcc28d4eca7d5e6b82ef4d44e7
3 files changed
+14
-7
admin/src/InternetPage.ts
+8
-2
@@ -16,6 +16,7 @@ import { ALL, WITH_IP } from './countries'
16
import _ from 'lodash'
17
import { SvgIconProps } from '@mui/material/SvgIcon/SvgIcon'
18
import { ConfigForm } from './ConfigForm'
19
+import { DynamicDnsResult } from '../../src/ddns'
20
21
const COUNTRIES = ALL.filter(x => WITH_IP.includes(x.code))
22
@@ -51,15 +52,20 @@ export default function InternetPage() {
52
ddnsBox(),
53
)
54
55
+ function stripTags(html: string) {
56
+ return html.replace(/.+<body>(.+)<\/body>.+/is, (all,x) => x || all) // extract body, if any
57
+ .replace(/<[^>]+>/g, ' ')
58
+ }
59
+
60
function ddnsBox() {
55
- const { data } = useApiEvents('get_dynamic_dns_error')
61
+ const { data } = useApiEvents<DynamicDnsResult>('get_dynamic_dns_error')
62
const ref = useRef<any>()
63
useEffect(() => ref.current && restartAnimation(ref.current, '1s blink'), [data]);
64
return h(TitleCard, { icon: Dns, title: "Dynamic DNS updater" },
65
data && h(Flex, {},
66
data.error ? h(ErrorIcon, { color: 'error', ref }) : h(Check, { color: 'success', ref }),
67
formatTimestamp(data.ts), ' – ',
62
- prefix("Error: ", data.error) || "Updated successfully",
68
+ prefix("Error: ", stripTags(data.error)) || "Updated successfully",
69
),
70
"This tool can keep your domain updated with your latest IP address. Not every service is compatible, and most of them have their own software for the job, which is superior, but we offer this lightweight solution in case you are more keen to it.",
71
h(ConfigForm<{
shared/api.ts
+3
-3
@@ -134,9 +134,9 @@ export function apiEvents(cmd: string, params: Dict, cb:EventHandler) {
134
return source
135
}
136
137
-export function useApiEvents(cmd: string, params: Dict={}) {
138
- const [data, setData] = useStateMounted<any>(undefined)
139
- const [error, setError] = useStateMounted<any>(undefined)
137
+export function useApiEvents<T=any>(cmd: string, params: Dict={}) {
138
+ const [data, setData] = useStateMounted<T | undefined>(undefined)
139
+ const [error, setError] = useStateMounted<undefined | string>(undefined)
140
const [loading, setLoading] = useStateMounted(false)
141
useEffect(() => {
142
const src = apiEvents(cmd, params, (type, data) => {
src/ddns.ts
+3
-2
@@ -13,7 +13,8 @@ import { getPublicIps } from './nat'
13
const dynamicDnsUrl = defineConfig(CFG.dynamic_dns_url, '')
14
15
let stop: Callback | undefined
16
-let last: undefined | { ts: Date, error: string, url: string }
16
+export interface DynamicDnsResult { ts: string, error: string, url: string }
17
+let last: undefined | DynamicDnsResult
18
dynamicDnsUrl.sub(v => {
19
stop?.()
20
if (!v) return
@@ -33,7 +34,7 @@ dynamicDnsUrl.sub(v => {
34
const str = String(res.body).trim()
35
return (re ? str.match(re) : res.ok) ? '' : (str || res.statusMessage)
36
}, (err: any) => err.code || err.message || String(err) )
36
- last = { ts: new Date(), error, url }
37
+ last = { ts: new Date().toJSON(), error, url }
38
events.emit('dynamicDnsError', last)
39
console.log('dynamic dns update', error || 'ok')
40
})