Valinor项目:如何自定义错误消息内容
前言
在数据映射和验证过程中,清晰准确的错误提示信息对于开发者调试和用户体验至关重要。Valinor项目提供了强大的错误消息自定义功能,允许开发者根据实际需求灵活定制错误提示内容。本文将详细介绍Valinor中错误消息的自定义方法。
基础消息定制
Valinor允许开发者通过占位符方式修改错误消息内容。系统提供了一系列预定义的占位符,可以动态插入到自定义消息中:
| 占位符 | 描述说明 | |---------------------|---------------------------------| | {message_code}
| 消息的唯一标识码 | | {node_name}
| 消息绑定的节点名称 | | {node_path}
| 消息绑定的节点路径 | | {node_type}
| 消息绑定的节点类型 | | {source_value}
| 节点接收到的原始输入值 | | {original_message}
| 自定义前的原始消息内容 |
使用示例
try {
(new \CuyZ\Valinor\MapperBuilder())
->mapper()
->map(SomeClass::class, [/* ... */]);
} catch (\CuyZ\Valinor\Mapper\MappingError $error) {
foreach ($error->messages() as $message) {
if ($message->code() === 'some_code') {
$message = $message
->withParameter('some_parameter', '自定义值')
->withBody('新消息 / {message_code} / {some_parameter}');
}
// 输出示例:新消息 / some_code / 自定义值
echo $message;
}
}
高级格式化功能
Valinor底层使用ICU库进行消息格式化,支持复杂的国际化格式处理,如货币、日期等专业格式化需求。
数值格式化示例
try {
(new \CuyZ\Valinor\MapperBuilder())->mapper()->map('int<0, 100>', 1337);
} catch (\CuyZ\Valinor\Mapper\MappingError $error) {
$message = $error->messages()->toArray()[0];
if (is_numeric($message->sourceValue())) {
$message = $message->withBody(
'无效金额: {source_value, number, currency}'
);
}
// 不同地区的货币格式输出
echo $message->withLocale('en_US'); // $1,337.00
echo $message->withLocale('en_GB'); // £1,337.00
echo $message->withLocale('fr_FR'); // 1 337,00 €
}
注意:要使用完整的ICU格式化功能,需要确保PHP安装了intl扩展。如果没有安装,Valinor会使用简化版的占位符替换功能,但无法处理复杂的格式化语法。
深度消息定制方案
对于更复杂的定制需求,Valinor提供了多种格式化器(Formatter)来处理消息内容和参数。
1. 国际化翻译格式化器
TranslationMessageFormatter
专门用于消息内容的国际化翻译:
\CuyZ\Valinor\Mapper\Tree\Message\Formatter\TranslationMessageFormatter::default()
// 添加/覆盖单个翻译项
->withTranslation('zh', 'some custom message', '自定义消息')
// 批量添加翻译项
->withTranslations([
'some custom message' => [
'en' => 'Some custom message',
'zh' => '自定义消息',
'ja' => 'カスタムメッセージ',
],
// 其他消息翻译...
])
->format($message);
2. 消息映射格式化器
MessageMapFormatter
提供了更灵活的消息替换机制,支持基于多种条件进行消息替换:
(new \CuyZ\Valinor\Mapper\Tree\Message\Formatter\MessageMapFormatter([
// 匹配特定消息码
'some_code' => '新内容 / 代码: {message_code}',
// 匹配特定消息内容
'原始消息内容' => '新内容 / 原消息: {original_message}',
// 匹配特定错误类型
SomeError::class => '新内容 / 值: {source_value}',
// 使用回调函数进行复杂处理
OtherError::class => function (NodeMessage $message): string {
return $message->path() === 'foo.bar'
? '特定路径错误'
: $message->body();
},
// 延迟回调处理
'foo' => fn () => $translator->translate('foo.bar'),
]))
// 设置默认消息
->defaultsTo('默认错误消息')
->format($message);
3. 组合格式化器
AggregateMessageFormatter
可以将多个格式化器组合使用,按顺序依次处理消息:
(new \CuyZ\Valinor\Mapper\Tree\Message\Formatter\AggregateMessageFormatter(
new \CuyZ\Valinor\Mapper\Tree\Message\Formatter\LocaleMessageFormatter('zh'),
new \CuyZ\Valinor\Mapper\Tree\Message\Formatter\MessageMapFormatter([/*...*/]),
\CuyZ\Valinor\Mapper\Tree\Message\Formatter\TranslationMessageFormatter::default(),
))->format($message);
最佳实践建议
- 分层处理:建议先使用消息映射处理特定错误,再用翻译器处理通用消息
- 性能优化:对于需要外部服务(如翻译API)的处理,使用回调函数延迟执行
- 默认值:始终为消息映射设置合理的默认值,确保系统健壮性
- 本地化:根据用户区域设置动态调整消息格式和语言
通过Valinor提供的这些灵活机制,开发者可以构建出既符合业务需求又用户友好的错误提示系统,大大提升开发效率和用户体验。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考