Skip to content

Commit 6aac147

Browse files
committed
better error reporting from IntlMessage constructor
All possible failures when calling IntlMessage::__construct() would be masked away with a generic "Constructor failed" message. This would include invalid patterns. This commit makes sure that the underlying error that caused the constructor failure is reported as part of the IntlException error message. Additionally, similar to the previous commit, this also uses this improved error reporting facility to also report details on parsing errors while trying to parse the message pattern
1 parent 917cc8a commit 6aac147

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

ext/intl/msgformat/msgformat.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
3434
int spattern_len = 0;
3535
zval* object;
3636
MessageFormatter_object* mfo;
37+
UParseError parse_error;
38+
3739
intl_error_reset( NULL );
3840

3941
object = return_value;
@@ -74,12 +76,26 @@ static int msgfmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
7476
(mfo)->mf_data.orig_format_len = pattern_len;
7577

7678
/* Create an ICU message formatter. */
77-
MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, locale, NULL, &INTL_DATA_ERROR_CODE(mfo));
79+
MSG_FORMAT_OBJECT(mfo) = umsg_open(spattern, spattern_len, locale, &parse_error, &INTL_DATA_ERROR_CODE(mfo));
7880

7981
if(spattern) {
8082
efree(spattern);
8183
}
8284

85+
if (INTL_DATA_ERROR_CODE( mfo ) == U_PATTERN_SYNTAX_ERROR) {
86+
char *msg = NULL;
87+
smart_str parse_error_str;
88+
parse_error_str = intl_parse_error_to_string( &parse_error );
89+
spprintf( &msg, 0, "pattern syntax error (%s)", parse_error_str.s? ZSTR_VAL(parse_error_str.s) : "unknown parser error" );
90+
smart_str_free( &parse_error_str );
91+
92+
intl_error_set_code( NULL, INTL_DATA_ERROR_CODE( mfo ) );
93+
intl_errors_set_custom_msg( INTL_DATA_ERROR_P( mfo ), msg, 1 );
94+
95+
efree( msg );
96+
return FAILURE;
97+
}
98+
8399
INTL_CTOR_CHECK_STATUS(mfo, "msgfmt_create: message formatter creation failed");
84100
return SUCCESS;
85101
}
@@ -105,7 +121,9 @@ PHP_METHOD( MessageFormatter, __construct )
105121
return_value = ZEND_THIS;
106122
if (msgfmt_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU) == FAILURE) {
107123
if (!EG(exception)) {
108-
zend_throw_exception(IntlException_ce_ptr, "Constructor failed", 0);
124+
zend_string *err = intl_error_get_message(NULL);
125+
zend_throw_exception(IntlException_ce_ptr, ZSTR_VAL(err), intl_error_get_code(NULL));
126+
zend_string_release_ex(err, 0);
109127
}
110128
}
111129
zend_restore_error_handling(&error_handling);

ext/intl/tests/msgfmt_fail2.phpt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,12 @@ ArgumentCountError: msgfmt_create() expects exactly 2 arguments, 1 given in %s o
126126
ArgumentCountError: MessageFormatter::create() expects exactly 2 arguments, 1 given in %s on line %d
127127
'U_ZERO_ERROR'
128128

129-
IntlException: Constructor failed in %s on line %d
129+
IntlException: msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR in %s on line %d
130130
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
131131
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
132132
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
133133

134-
IntlException: Constructor failed in %s on line %d
134+
IntlException: msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR in %s on line %d
135135
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
136136
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
137137
'msgfmt_create: message formatter creation failed: U_ILLEGAL_ARGUMENT_ERROR'
@@ -145,17 +145,17 @@ TypeError: MessageFormatter::create(): Argument #1 ($locale) must be of type str
145145
TypeError: msgfmt_create(): Argument #1 ($locale) must be of type string, array given in %s on line %d
146146
'U_ZERO_ERROR'
147147

148-
IntlException: Constructor failed in %s on line %d
148+
IntlException: pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR in %s on line %d
149149
'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR'
150150
'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR'
151151
'pattern syntax error (parse error at offset 1, after "{", before or at "0,choice}"): U_PATTERN_SYNTAX_ERROR'
152152

153-
IntlException: Constructor failed in %s on line %d
153+
IntlException: msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES in %s on line %d
154154
'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES'
155155
'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES'
156156
'msgfmt_create: message formatter creation failed: U_UNMATCHED_BRACES'
157157

158-
IntlException: Constructor failed in %s on line %d
158+
IntlException: msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND in %s on line %d
159159
'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND'
160160
'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND'
161161
'msgfmt_create: error converting pattern to UTF-16: U_INVALID_CHAR_FOUND'

0 commit comments

Comments
 (0)