{"record":{"id":"faef6149c026512f","repo":"nodejs/node","slug":"error-at-s-s","errorCode":null,"errorMessage":"error at %s: %s\n","messagePattern":"error at (.+?): (.+?)\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"deps/icu-small/source/tools/toolutil/toolutil.cpp","lineNumber":85,"sourceCode":"#include \"unicode/errorcode.h\"\n#include \"unicode/putil.h\"\n#include \"unicode/uchar.h\"\n#include \"unicode/umutablecptrie.h\"\n#include \"unicode/ucptrie.h\"\n#include \"cmemory.h\"\n#include \"cstring.h\"\n#include \"toolutil.h\"\n#include \"uassert.h\"\n\nU_NAMESPACE_BEGIN\n\nIcuToolErrorCode::~IcuToolErrorCode() {\n    // Safe because our handleFailure() does not throw exceptions.\n    if(isFailure()) { handleFailure(); }\n}\n\nvoid IcuToolErrorCode::handleFailure() const {\n    fprintf(stderr, \"error at %s: %s\\n\", location, errorName());\n    exit(errorCode);\n}\n\nnamespace toolutil {\n\nvoid setCPTrieBit(UMutableCPTrie *mutableCPTrie,\n                  UChar32 start, UChar32 end, int32_t shift, bool on, UErrorCode &errorCode) {\n    uint32_t mask = U_MASK(shift);\n    uint32_t value = on ? mask : 0;\n    setCPTrieBits(mutableCPTrie, start, end, mask, value, errorCode);\n}\n\nvoid setCPTrieBits(UMutableCPTrie *mutableCPTrie,\n                   UChar32 start, UChar32 end, uint32_t mask, uint32_t value,\n                   UErrorCode &errorCode) {\n    if (U_FAILURE(errorCode)) { return; }\n    // The value must not have any bits set outside of the mask.\n    if ((value & ~mask) != 0) {","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/icu-small/source/tools/toolutil/toolutil.cpp#L67-L103","documentation":"This is the generic fatal error handler for ICU build tools. IcuToolErrorCode is a RAII wrapper around UErrorCode; when an instance with a failure state is destroyed, handleFailure() prints 'error at <location>: <errorName>' and calls exit(errorCode). The location string is set when the IcuToolErrorCode is constructed or assigned, identifying which tool operation failed.","triggerScenarios":"Any ICU build tool (genrb, gencnval, gennorm2, etc.) using IcuToolErrorCode that encounters a U_FAILURE code and lets the error code object go out of scope without being checked and handled. The destructor detects isFailure() and calls exit() with the numeric ICU error code as the process exit code.","commonSituations":"Any unrecoverable ICU error during data building — missing input files, corrupted data, parse failures in upstream code, invalid arguments to ICU APIs. The error message will contain the location tag and the ICU error name (e.g., 'U_PARSE_ERROR', 'U_MEMORY_ALLOCATION_ERROR').","solutions":["Read the error name in the message to identify the underlying ICU error code.","Use the location string to find which tool function or operation failed.","Address the root cause indicated by the specific UErrorCode value (e.g., fix the parse error, provide the missing file).","If developing a custom tool, check the IcuToolErrorCode before it goes out of scope and handle failures gracefully instead of relying on the destructor's exit()."],"exampleFix":"// before — unhandled error code falls through to destructor\nIcuToolErrorCode status(\"myop\");\nsomeIcuApi(&status);\n// status goes out of scope, triggers exit()\n\n// after — check before scope exit\nIcuToolErrorCode status(\"myop\");\nsomeIcuApi(&status);\nif (status.isFailure()) {\n    fprintf(stderr, \"custom handling: %s\\n\", status.errorName());\n    status.reset();  // prevent destructor exit\n    return 1;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// IcuToolErrorCode is a RAII wrapper — handle errors before scope exit\n#include \"toolutil.h\"\n\nvoid safeIcuOperation() {\n    icu::IcuToolErrorCode status(\"myOperation\");\n    someIcuApi(&status);\n    if (status.isFailure()) {\n        // Handle gracefully instead of letting destructor call exit()\n        fprintf(stderr, \"Operation failed: %s at %s\\n\",\n                status.errorName(), status.location);\n        status.reset();  // Clear failure to prevent destructor exit\n        return;\n    }\n    // Success path — status goes out of scope with no failure, no exit\n}","preventionTips":["Always check IcuToolErrorCode::isFailure() before the object goes out of scope.","Call reset() to clear failure state if you handle the error yourself.","Use setGlobalContext() to provide meaningful location strings for debugging.","Prefer explicit error handling over relying on the RAII destructor's exit() behavior."],"tags":["icu","tool-error","fatal-exit","raii","build-tool"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}