88#include " eden/fs/telemetry/EdenErrorInfoBuilder.h"
99#include < gtest/gtest.h>
1010#include < cerrno>
11+ #include < stdexcept>
1112#include < system_error>
1213
14+ #include < folly/CPortability.h>
15+
16+ #include " eden/fs/telemetry/ErrorArg.h"
17+
1318using namespace facebook ::eden;
1419
20+ namespace {
21+ [[noreturn]] FOLLY_NOINLINE void throwRuntimeError () {
22+ throw std::runtime_error (" fuse read failed" );
23+ }
24+ } // namespace
25+
1526TEST (EdenErrorInfoTest, InitializeFuseEdenErrorInfoWithException) {
16- std::runtime_error ex (" fuse read failed" );
17- int line = __LINE__ + 1 ;
18- auto info = EdenErrorInfo::fuse (ex, 42 , " /mnt/repo" ).create ();
27+ try {
28+ throwRuntimeError ();
29+ } catch (const std::exception& ex) {
30+ // ErrorArg captures the throw-site stack trace inside a catch block.
31+ ErrorArg error (ex);
32+ #ifdef __linux__
33+ ASSERT_TRUE (error.stackTrace .has_value ())
34+ << " ErrorArg should capture a stack trace from a thrown exception" ;
35+ EXPECT_NE (error.stackTrace ->find (" throwRuntimeError" ), std::string::npos)
36+ << " Stack trace should contain the throwing function, got: "
37+ << *error.stackTrace ;
38+ #endif
1939
20- EXPECT_EQ (info.component , EdenComponent::Fuse);
21- EXPECT_EQ (info.errorMessage , " fuse read failed" );
22- EXPECT_EQ (info.inode .value (), 42 );
23- EXPECT_EQ (info.mountPoint .value (), " /mnt/repo" );
24- EXPECT_FALSE (info.errorCode .has_value ());
25- EXPECT_NE (
26- info.exceptionType .value ().find (" runtime_error" ), std::string::npos);
27- EXPECT_TRUE (info.stackTrace .has_value ());
28- auto & trace = info.stackTrace .value ();
29- EXPECT_NE (trace.find (" EdenErrorInfoBuilderTest.cpp" ), std::string::npos);
30- EXPECT_NE (trace.find (" :" + std::to_string (line) + " in " ), std::string::npos);
31- EXPECT_NE (trace.find (" TestBody" ), std::string::npos);
40+ // create() stores the raw combined trace in info.stackTrace.
41+ auto info = EdenErrorInfo::fuse (ex, 42 , " /mnt/repo" ).create ();
42+
43+ EXPECT_EQ (info.component , EdenComponent::Fuse);
44+ EXPECT_EQ (info.errorMessage , " fuse read failed" );
45+ EXPECT_EQ (info.inode .value (), 42 );
46+ EXPECT_EQ (info.mountPoint .value (), " /mnt/repo" );
47+ EXPECT_FALSE (info.errorCode .has_value ());
48+ EXPECT_NE (
49+ info.exceptionType .value ().find (" runtime_error" ), std::string::npos);
50+ ASSERT_TRUE (info.stackTrace .has_value ());
51+ EXPECT_NE (
52+ info.stackTrace ->find (" EdenErrorInfoBuilderTest.cpp" ),
53+ std::string::npos)
54+ << " Stack trace should contain source file, got: " << *info.stackTrace ;
55+ #ifdef __linux__
56+ EXPECT_NE (info.stackTrace ->find (" Stack trace:" ), std::string::npos)
57+ << " Stack trace should contain raw trace section, got: "
58+ << *info.stackTrace ;
59+ #endif
60+ }
3261}
3362
3463TEST (EdenErrorInfoTest, InitializeFuseEdenErrorInfoWithStringMessage) {
@@ -41,10 +70,10 @@ TEST(EdenErrorInfoTest, InitializeFuseEdenErrorInfoWithStringMessage) {
4170 EXPECT_FALSE (info.errorCode .has_value ());
4271 EXPECT_FALSE (info.errorName .has_value ());
4372 EXPECT_FALSE (info.exceptionType .has_value ());
44- EXPECT_TRUE (info.stackTrace .has_value ());
45- auto & loc = info. stackTrace . value ();
46- EXPECT_NE (loc. find (" EdenErrorInfoBuilderTest.cpp" ), std::string::npos)
47- << " Expected source file in location , got: " << loc ;
73+ ASSERT_TRUE (info.stackTrace .has_value ());
74+ EXPECT_NE (
75+ info. stackTrace -> find (" EdenErrorInfoBuilderTest.cpp" ), std::string::npos)
76+ << " Stack trace should contain source file , got: " << *info. stackTrace ;
4877}
4978
5079TEST (EdenErrorInfoTest, FuseErrorInfoOverridesErrorCodeAndName) {
0 commit comments