@@ -287,6 +287,15 @@ private static void logSearchSpend(String sub, long start, boolean found) {
287287 /**
288288 * find the most similar error code elaboration for the given error message.
289289 *
290+ * The method uses a two-phase strategy to avoid performance degradation
291+ * when format args produce very long strings (e.g., serialized error chains
292+ * or HTML response bodies):
293+ *
294+ * Phase 1: Try regex matching with the formatted string (length-guarded).
295+ * Phase 2: If Phase 1 misses (or formatted string too long), fallback
296+ * to the raw fmt template for regex matching.
297+ * Phase 3: Distance matching always uses the raw fmt template.
298+ *
290299 * @param sub error message or error message fmt
291300 * @param args arguments
292301 * @return the most similar error code elaboration
@@ -311,23 +320,41 @@ public static ErrorCodeElaboration findSimilar(String sub, Object...args) {
311320 errors .remove (sub );
312321 }
313322
314- if (args != null && missed .get (String .format (sub , args )) != null ) {
315- logSearchSpend (sub , start , false );
316- return null ;
317- } else if (missed .get (sub ) != null ) {
323+ // check missed cache for both fmt template and formatted string
324+ if (missed .get (sub ) != null ) {
318325 logSearchSpend (sub , start , false );
319326 return null ;
320327 }
328+ if (args != null ) {
329+ try {
330+ String formatted = String .format (sub , args );
331+ if (missed .get (formatted ) != null ) {
332+ logSearchSpend (sub , start , false );
333+ return null ;
334+ }
335+ } catch (Exception e ) {
336+ logger .trace (String .format ("failed to format elaboration key: %s" , e .getMessage ()));
337+ }
338+ }
321339
322- try {
323- logger .trace (String .format ("start to search elaboration for: %s" , String .format (sub , args )));
324- err = findMostSimilarRegex (String .format (sub , args ));
325- } catch (Exception e ) {
326- logger .trace (String .format ("start search elaboration for: %s" , sub ));
340+ // Phase 1: try regex matching with formatted string (guarded by length limit)
341+ if (args != null && args .length > 0 ) {
342+ try {
343+ String formatted = String .format (sub , args );
344+ if (formatted .length () <= maxElaborationRegex ) {
345+ err = findMostSimilarRegex (formatted );
346+ }
347+ } catch (Exception e ) {
348+ logger .trace (String .format ("failed to format for regex matching: %s" , e .getMessage ()));
349+ }
350+ }
351+
352+ // Phase 2: if formatted string missed or was too long, fallback to raw fmt template
353+ if (err == null ) {
327354 err = findMostSimilarRegex (sub );
328355 }
329356
330- // find by distance is not reliable disable it for now
357+ // Phase 3: distance matching uses the raw fmt template (always short)
331358 if (err == null ) {
332359 err = findSimilarDistance (sub );
333360 }
@@ -355,6 +382,10 @@ private static boolean verifyElaboration(ErrorCodeElaboration elaboration, Strin
355382
356383 // better precision, worse performance
357384 private static ErrorCodeElaboration findMostSimilarRegex (String sub ) {
385+ if (sub .length () > maxElaborationRegex ) {
386+ return null ;
387+ }
388+
358389 if (!isRegexMatchedByRetrees (sub )) {
359390 return null ;
360391 }
0 commit comments