日志与错误处理基础:别只把失败写进控制台
【摘要】 日志和错误处理是后续系统能力 Demo 的底座。页面 Demo 不能只调用 console 或 hilog 后没有反馈,用户需要能看到当前动作是否成功、失败原因是什么。 本页演示三种最小能力: hilog.info:记录普通流程。 hilog.warn:记录可降级但需要关注的状态。 BusinessError:显示 c
日志与错误处理基础:别只把失败写进控制台
日志和错误处理是后续系统能力 Demo 的底座。页面 Demo 不能只调用 console 或 hilog 后没有反馈,用户需要能看到当前动作是否成功、失败原因是什么。
本页演示三种最小能力:
hilog.info:记录普通流程。hilog.warn:记录可降级但需要关注的状态。BusinessError:显示code/message,不静默吞掉。
交互预期
- 点击“写 info”,页面新增 info 记录,最近错误变为“暂无错误”。
- 点击“写 warn”,页面新增 warn 记录,说明这是可降级状态。
- 点击“模拟错误”,页面显示
code=401, message=标题不能为空。 - 点击“清空日志”,列表回到等待操作状态。
完整示例代码
import { BusinessError } from '@kit.BasicServicesKit'
import { hilog } from '@kit.PerformanceAnalysisKit'
const ENGINEERING_LOG_DOMAIN: number = 0x1200
const ENGINEERING_LOG_TAG: string = 'EngineeringDemo'
class DemoBusinessError extends Error implements BusinessError {
code: number
constructor(code: number, message: string) {
super(message)
this.code = code
}
}
class EngineeringLogEntry {
level: string
message: string
detail: string
constructor(level: string, message: string, detail: string) {
this.level = level
this.message = message
this.detail = detail
}
}
@Entry
@Component
struct LogErrorHandlingDemo {
@State feedback: string = '点击按钮后,页面内会同步展示日志意图和错误处理结果。'
@State lastError: string = '暂无错误'
@State logEntries: EngineeringLogEntry[] = [
new EngineeringLogEntry('info', '等待操作', '日志不要只写到控制台,关键结果也要让 Demo 页面可见。')
]
private errorToText(error: BusinessError): string {
return `code=${error.code}, message=${error.message}`
}
private addLog(level: string, message: string, detail: string): void {
const entries: EngineeringLogEntry[] = [
new EngineeringLogEntry(level, message, detail)
]
this.logEntries.forEach((item: EngineeringLogEntry) => {
if (entries.length < 4) {
entries.push(item)
}
})
this.logEntries = entries
}
private writeInfoLog(): void {
hilog.info(ENGINEERING_LOG_DOMAIN, ENGINEERING_LOG_TAG, 'User tapped info log')
this.lastError = '暂无错误'
this.feedback = '已写入 info 级别日志,并在页面内留下可见记录。'
this.addLog('info', '记录普通流程', '适合记录用户触发、页面进入、轻量状态变化。')
}
private writeWarnLog(): void {
hilog.warn(ENGINEERING_LOG_DOMAIN, ENGINEERING_LOG_TAG, 'User tapped warning log')
this.lastError = '暂无错误'
this.feedback = '已写入 warn 级别日志,用来表示可降级但需要关注的状态。'
this.addLog('warn', '记录降级状态', '适合记录能力不可用、用户未授权、缓存为空等可恢复状态。')
}
private simulateBusinessError(): void {
try {
this.validateRequiredTitle('')
} catch (error) {
const businessError = error as BusinessError
const errorText: string = this.errorToText(businessError)
hilog.error(ENGINEERING_LOG_DOMAIN, ENGINEERING_LOG_TAG, 'BusinessError %{public}s', errorText)
this.lastError = errorText
this.feedback = '已捕获 BusinessError,错误码和消息都显示在页面内。'
this.addLog('error', '捕获业务错误', errorText)
}
}
private validateRequiredTitle(title: string): void {
if (title.length === 0) {
throw new DemoBusinessError(401, '标题不能为空')
}
}
private clearLogs(): void {
this.lastError = '暂无错误'
this.feedback = '日志列表已清空。'
this.logEntries = [
new EngineeringLogEntry('info', '等待操作', '继续点击按钮可重新生成日志记录。')
]
}
private levelColor(level: string): string {
if (level === 'error') {
return '#DC2626'
}
if (level === 'warn') {
return '#B45309'
}
return '#2563EB'
}
@Builder
logCard(index: number) {
Column({ space: 8 }) {
Row() {
Text(this.logEntries[index].level)
.fontSize(12)
.fontColor('#FFFFFF')
.padding({ left: 8, right: 8, top: 4, bottom: 4 })
.backgroundColor(this.levelColor(this.logEntries[index].level))
.borderRadius(8)
Blank()
}
.width('100%')
Text(this.logEntries[index].message)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text(this.logEntries[index].detail)
.fontSize(13)
.fontColor('#4B5563')
.lineHeight(20)
}
.width('100%')
.padding(14)
.borderRadius(12)
.backgroundColor('#FFFFFF')
.border({ width: 1, color: '#E5E7EB' })
.alignItems(HorizontalAlign.Start)
}
build() {
Scroll() {
Column({ space: 20 }) {
Column({ space: 8 }) {
Text('日志与错误处理基础')
.fontSize(28)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text('日志分级要表达状态,错误处理要把 code 和 message 留出来。')
.fontSize(14)
.fontColor('#4B5563')
.lineHeight(22)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
Row({ space: 10 }) {
Button('写 info')
.height(46)
.layoutWeight(1)
.fontSize(14)
.backgroundColor('#2563EB')
.onClick(() => {
this.writeInfoLog()
})
Button('写 warn')
.height(46)
.layoutWeight(1)
.fontSize(14)
.backgroundColor('#B45309')
.onClick(() => {
this.writeWarnLog()
})
Button('模拟错误')
.height(46)
.layoutWeight(1)
.fontSize(14)
.backgroundColor('#DC2626')
.onClick(() => {
this.simulateBusinessError()
})
}
.width('100%')
Button('清空日志')
.height(46)
.width('100%')
.fontSize(15)
.fontColor('#334155')
.backgroundColor('#E5E7EB')
.onClick(() => {
this.clearLogs()
})
Text(this.feedback)
.width('100%')
.fontSize(14)
.fontColor('#1D4ED8')
.lineHeight(22)
.padding(12)
.backgroundColor('#EFF6FF')
.borderRadius(10)
Column({ space: 8 }) {
Text('最近错误')
.fontSize(17)
.fontWeight(FontWeight.Bold)
.fontColor('#111827')
Text(this.lastError)
.fontSize(13)
.fontColor(this.lastError === '暂无错误' ? '#4B5563' : '#DC2626')
.lineHeight(20)
}
.width('100%')
.padding(16)
.borderRadius(14)
.backgroundColor('#FFFFFF')
.border({ width: 1, color: '#E5E7EB' })
.alignItems(HorizontalAlign.Start)
ForEach(this.logEntries, (item: EngineeringLogEntry, index: number) => {
this.logCard(index)
}, (item: EngineeringLogEntry) => item.message + item.detail)
}
.width('100%')
.padding(24)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.height('100%')
.backgroundColor('#F8FAFC')
}
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)