1 //===----- unittests/ErrorTest.cpp - Error.h tests ------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/Support/Error.h" 11 #include "llvm-c/Error.h" 12 13 #include "llvm/ADT/Twine.h" 14 #include "llvm/Support/Errc.h" 15 #include "llvm/Support/ErrorHandling.h" 16 #include "llvm/Support/ManagedStatic.h" 17 #include "llvm/Testing/Support/Error.h" 18 #include "gtest/gtest-spi.h" 19 #include "gtest/gtest.h" 20 #include <memory> 21 22 using namespace llvm; 23 24 namespace { 25 26 // Custom error class with a default base class and some random 'info' attached. 27 class CustomError : public ErrorInfo<CustomError> { 28 public: 29 // Create an error with some info attached. 30 CustomError(int Info) : Info(Info) {} 31 32 // Get the info attached to this error. 33 int getInfo() const { return Info; } 34 35 // Log this error to a stream. 36 void log(raw_ostream &OS) const override { 37 OS << "CustomError {" << getInfo() << "}"; 38 } 39 40 std::error_code convertToErrorCode() const override { 41 llvm_unreachable("CustomError doesn't support ECError conversion"); 42 } 43 44 // Used by ErrorInfo::classID. 45 static char ID; 46 47 protected: 48 // This error is subclassed below, but we can't use inheriting constructors 49 // yet, so we can't propagate the constructors through ErrorInfo. Instead 50 // we have to have a default constructor and have the subclass initialize all 51 // fields. 52 CustomError() : Info(0) {} 53 54 int Info; 55 }; 56 57 char CustomError::ID = 0; 58 59 // Custom error class with a custom base class and some additional random 60 // 'info'. 61 class CustomSubError : public ErrorInfo<CustomSubError, CustomError> { 62 public: 63 // Create a sub-error with some info attached. 64 CustomSubError(int Info, int ExtraInfo) : ExtraInfo(ExtraInfo) { 65 this->Info = Info; 66 } 67 68 // Get the extra info attached to this error. 69 int getExtraInfo() const { return ExtraInfo; } 70 71 // Log this error to a stream. 72 void log(raw_ostream &OS) const override { 73 OS << "CustomSubError { " << getInfo() << ", " << getExtraInfo() << "}"; 74 } 75 76 std::error_code convertToErrorCode() const override { 77 llvm_unreachable("CustomSubError doesn't support ECError conversion"); 78 } 79 80 // Used by ErrorInfo::classID. 81 static char ID; 82 83 protected: 84 int ExtraInfo; 85 }; 86 87 char CustomSubError::ID = 0; 88 89 static Error handleCustomError(const CustomError &CE) { 90 return Error::success(); 91 } 92 93 static void handleCustomErrorVoid(const CustomError &CE) {} 94 95 static Error handleCustomErrorUP(std::unique_ptr<CustomError> CE) { 96 return Error::success(); 97 } 98 99 static void handleCustomErrorUPVoid(std::unique_ptr<CustomError> CE) {} 100 101 // Test that success values implicitly convert to false, and don't cause crashes 102 // once they've been implicitly converted. 103 TEST(Error, CheckedSuccess) { 104 Error E = Error::success(); 105 EXPECT_FALSE(E) << "Unexpected error while testing Error 'Success'"; 106 } 107 108 // Test that unchecked success values cause an abort. 109 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 110 TEST(Error, UncheckedSuccess) { 111 EXPECT_DEATH({ Error E = Error::success(); }, 112 "Program aborted due to an unhandled Error:") 113 << "Unchecked Error Succes value did not cause abort()"; 114 } 115 #endif 116 117 // ErrorAsOutParameter tester. 118 void errAsOutParamHelper(Error &Err) { 119 ErrorAsOutParameter ErrAsOutParam(&Err); 120 // Verify that checked flag is raised - assignment should not crash. 121 Err = Error::success(); 122 // Raise the checked bit manually - caller should still have to test the 123 // error. 124 (void)!!Err; 125 } 126 127 // Test that ErrorAsOutParameter sets the checked flag on construction. 128 TEST(Error, ErrorAsOutParameterChecked) { 129 Error E = Error::success(); 130 errAsOutParamHelper(E); 131 (void)!!E; 132 } 133 134 // Test that ErrorAsOutParameter clears the checked flag on destruction. 135 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 136 TEST(Error, ErrorAsOutParameterUnchecked) { 137 EXPECT_DEATH({ Error E = Error::success(); errAsOutParamHelper(E); }, 138 "Program aborted due to an unhandled Error:") 139 << "ErrorAsOutParameter did not clear the checked flag on destruction."; 140 } 141 #endif 142 143 // Check that we abort on unhandled failure cases. (Force conversion to bool 144 // to make sure that we don't accidentally treat checked errors as handled). 145 // Test runs in debug mode only. 146 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 147 TEST(Error, UncheckedError) { 148 auto DropUnhandledError = []() { 149 Error E = make_error<CustomError>(42); 150 (void)!E; 151 }; 152 EXPECT_DEATH(DropUnhandledError(), 153 "Program aborted due to an unhandled Error:") 154 << "Unhandled Error failure value did not cause abort()"; 155 } 156 #endif 157 158 // Check 'Error::isA<T>' method handling. 159 TEST(Error, IsAHandling) { 160 // Check 'isA' handling. 161 Error E = make_error<CustomError>(1); 162 Error F = make_error<CustomSubError>(1, 2); 163 Error G = Error::success(); 164 165 EXPECT_TRUE(E.isA<CustomError>()); 166 EXPECT_FALSE(E.isA<CustomSubError>()); 167 EXPECT_TRUE(F.isA<CustomError>()); 168 EXPECT_TRUE(F.isA<CustomSubError>()); 169 EXPECT_FALSE(G.isA<CustomError>()); 170 171 consumeError(std::move(E)); 172 consumeError(std::move(F)); 173 consumeError(std::move(G)); 174 } 175 176 // Check that we can handle a custom error. 177 TEST(Error, HandleCustomError) { 178 int CaughtErrorInfo = 0; 179 handleAllErrors(make_error<CustomError>(42), [&](const CustomError &CE) { 180 CaughtErrorInfo = CE.getInfo(); 181 }); 182 183 EXPECT_TRUE(CaughtErrorInfo == 42) << "Wrong result from CustomError handler"; 184 } 185 186 // Check that handler type deduction also works for handlers 187 // of the following types: 188 // void (const Err&) 189 // Error (const Err&) mutable 190 // void (const Err&) mutable 191 // Error (Err&) 192 // void (Err&) 193 // Error (Err&) mutable 194 // void (Err&) mutable 195 // Error (unique_ptr<Err>) 196 // void (unique_ptr<Err>) 197 // Error (unique_ptr<Err>) mutable 198 // void (unique_ptr<Err>) mutable 199 TEST(Error, HandlerTypeDeduction) { 200 201 handleAllErrors(make_error<CustomError>(42), [](const CustomError &CE) {}); 202 203 handleAllErrors( 204 make_error<CustomError>(42), 205 [](const CustomError &CE) mutable -> Error { return Error::success(); }); 206 207 handleAllErrors(make_error<CustomError>(42), 208 [](const CustomError &CE) mutable {}); 209 210 handleAllErrors(make_error<CustomError>(42), 211 [](CustomError &CE) -> Error { return Error::success(); }); 212 213 handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) {}); 214 215 handleAllErrors(make_error<CustomError>(42), 216 [](CustomError &CE) mutable -> Error { return Error::success(); }); 217 218 handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) mutable {}); 219 220 handleAllErrors( 221 make_error<CustomError>(42), 222 [](std::unique_ptr<CustomError> CE) -> Error { return Error::success(); }); 223 224 handleAllErrors(make_error<CustomError>(42), 225 [](std::unique_ptr<CustomError> CE) {}); 226 227 handleAllErrors( 228 make_error<CustomError>(42), 229 [](std::unique_ptr<CustomError> CE) mutable -> Error { return Error::success(); }); 230 231 handleAllErrors(make_error<CustomError>(42), 232 [](std::unique_ptr<CustomError> CE) mutable {}); 233 234 // Check that named handlers of type 'Error (const Err&)' work. 235 handleAllErrors(make_error<CustomError>(42), handleCustomError); 236 237 // Check that named handlers of type 'void (const Err&)' work. 238 handleAllErrors(make_error<CustomError>(42), handleCustomErrorVoid); 239 240 // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work. 241 handleAllErrors(make_error<CustomError>(42), handleCustomErrorUP); 242 243 // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work. 244 handleAllErrors(make_error<CustomError>(42), handleCustomErrorUPVoid); 245 } 246 247 // Test that we can handle errors with custom base classes. 248 TEST(Error, HandleCustomErrorWithCustomBaseClass) { 249 int CaughtErrorInfo = 0; 250 int CaughtErrorExtraInfo = 0; 251 handleAllErrors(make_error<CustomSubError>(42, 7), 252 [&](const CustomSubError &SE) { 253 CaughtErrorInfo = SE.getInfo(); 254 CaughtErrorExtraInfo = SE.getExtraInfo(); 255 }); 256 257 EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7) 258 << "Wrong result from CustomSubError handler"; 259 } 260 261 // Check that we trigger only the first handler that applies. 262 TEST(Error, FirstHandlerOnly) { 263 int DummyInfo = 0; 264 int CaughtErrorInfo = 0; 265 int CaughtErrorExtraInfo = 0; 266 267 handleAllErrors(make_error<CustomSubError>(42, 7), 268 [&](const CustomSubError &SE) { 269 CaughtErrorInfo = SE.getInfo(); 270 CaughtErrorExtraInfo = SE.getExtraInfo(); 271 }, 272 [&](const CustomError &CE) { DummyInfo = CE.getInfo(); }); 273 274 EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7 && 275 DummyInfo == 0) 276 << "Activated the wrong Error handler(s)"; 277 } 278 279 // Check that general handlers shadow specific ones. 280 TEST(Error, HandlerShadowing) { 281 int CaughtErrorInfo = 0; 282 int DummyInfo = 0; 283 int DummyExtraInfo = 0; 284 285 handleAllErrors( 286 make_error<CustomSubError>(42, 7), 287 [&](const CustomError &CE) { CaughtErrorInfo = CE.getInfo(); }, 288 [&](const CustomSubError &SE) { 289 DummyInfo = SE.getInfo(); 290 DummyExtraInfo = SE.getExtraInfo(); 291 }); 292 293 EXPECT_TRUE(CaughtErrorInfo == 42 && DummyInfo == 0 && DummyExtraInfo == 0) 294 << "General Error handler did not shadow specific handler"; 295 } 296 297 // Test joinErrors. 298 TEST(Error, CheckJoinErrors) { 299 int CustomErrorInfo1 = 0; 300 int CustomErrorInfo2 = 0; 301 int CustomErrorExtraInfo = 0; 302 Error E = 303 joinErrors(make_error<CustomError>(7), make_error<CustomSubError>(42, 7)); 304 305 handleAllErrors(std::move(E), 306 [&](const CustomSubError &SE) { 307 CustomErrorInfo2 = SE.getInfo(); 308 CustomErrorExtraInfo = SE.getExtraInfo(); 309 }, 310 [&](const CustomError &CE) { 311 // Assert that the CustomError instance above is handled 312 // before the 313 // CustomSubError - joinErrors should preserve error 314 // ordering. 315 EXPECT_EQ(CustomErrorInfo2, 0) 316 << "CustomErrorInfo2 should be 0 here. " 317 "joinErrors failed to preserve ordering.\n"; 318 CustomErrorInfo1 = CE.getInfo(); 319 }); 320 321 EXPECT_TRUE(CustomErrorInfo1 == 7 && CustomErrorInfo2 == 42 && 322 CustomErrorExtraInfo == 7) 323 << "Failed handling compound Error."; 324 325 // Test appending a single item to a list. 326 { 327 int Sum = 0; 328 handleAllErrors( 329 joinErrors( 330 joinErrors(make_error<CustomError>(7), 331 make_error<CustomError>(7)), 332 make_error<CustomError>(7)), 333 [&](const CustomError &CE) { 334 Sum += CE.getInfo(); 335 }); 336 EXPECT_EQ(Sum, 21) << "Failed to correctly append error to error list."; 337 } 338 339 // Test prepending a single item to a list. 340 { 341 int Sum = 0; 342 handleAllErrors( 343 joinErrors( 344 make_error<CustomError>(7), 345 joinErrors(make_error<CustomError>(7), 346 make_error<CustomError>(7))), 347 [&](const CustomError &CE) { 348 Sum += CE.getInfo(); 349 }); 350 EXPECT_EQ(Sum, 21) << "Failed to correctly prepend error to error list."; 351 } 352 353 // Test concatenating two error lists. 354 { 355 int Sum = 0; 356 handleAllErrors( 357 joinErrors( 358 joinErrors( 359 make_error<CustomError>(7), 360 make_error<CustomError>(7)), 361 joinErrors( 362 make_error<CustomError>(7), 363 make_error<CustomError>(7))), 364 [&](const CustomError &CE) { 365 Sum += CE.getInfo(); 366 }); 367 EXPECT_EQ(Sum, 28) << "Failed to correctly concatenate error lists."; 368 } 369 } 370 371 // Test that we can consume success values. 372 TEST(Error, ConsumeSuccess) { 373 Error E = Error::success(); 374 consumeError(std::move(E)); 375 } 376 377 TEST(Error, ConsumeError) { 378 Error E = make_error<CustomError>(7); 379 consumeError(std::move(E)); 380 } 381 382 // Test that handleAllUnhandledErrors crashes if an error is not caught. 383 // Test runs in debug mode only. 384 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 385 TEST(Error, FailureToHandle) { 386 auto FailToHandle = []() { 387 handleAllErrors(make_error<CustomError>(7), [&](const CustomSubError &SE) { 388 errs() << "This should never be called"; 389 exit(1); 390 }); 391 }; 392 393 EXPECT_DEATH(FailToHandle(), 394 "Failure value returned from cantFail wrapped call") 395 << "Unhandled Error in handleAllErrors call did not cause an " 396 "abort()"; 397 } 398 #endif 399 400 // Test that handleAllUnhandledErrors crashes if an error is returned from a 401 // handler. 402 // Test runs in debug mode only. 403 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 404 TEST(Error, FailureFromHandler) { 405 auto ReturnErrorFromHandler = []() { 406 handleAllErrors(make_error<CustomError>(7), 407 [&](std::unique_ptr<CustomSubError> SE) { 408 return Error(std::move(SE)); 409 }); 410 }; 411 412 EXPECT_DEATH(ReturnErrorFromHandler(), 413 "Failure value returned from cantFail wrapped call") 414 << " Error returned from handler in handleAllErrors call did not " 415 "cause abort()"; 416 } 417 #endif 418 419 // Test that we can return values from handleErrors. 420 TEST(Error, CatchErrorFromHandler) { 421 int ErrorInfo = 0; 422 423 Error E = handleErrors( 424 make_error<CustomError>(7), 425 [&](std::unique_ptr<CustomError> CE) { return Error(std::move(CE)); }); 426 427 handleAllErrors(std::move(E), 428 [&](const CustomError &CE) { ErrorInfo = CE.getInfo(); }); 429 430 EXPECT_EQ(ErrorInfo, 7) 431 << "Failed to handle Error returned from handleErrors."; 432 } 433 434 TEST(Error, StringError) { 435 std::string Msg; 436 raw_string_ostream S(Msg); 437 logAllUnhandledErrors(make_error<StringError>("foo" + Twine(42), 438 inconvertibleErrorCode()), 439 S, ""); 440 EXPECT_EQ(S.str(), "foo42\n") << "Unexpected StringError log result"; 441 442 auto EC = 443 errorToErrorCode(make_error<StringError>("", errc::invalid_argument)); 444 EXPECT_EQ(EC, errc::invalid_argument) 445 << "Failed to convert StringError to error_code."; 446 } 447 448 TEST(Error, createStringError) { 449 static const char *Bar = "bar"; 450 static const std::error_code EC = errc::invalid_argument; 451 std::string Msg; 452 raw_string_ostream S(Msg); 453 logAllUnhandledErrors(createStringError(EC, "foo%s%d0x%" PRIx8, Bar, 1, 0xff), 454 S, ""); 455 EXPECT_EQ(S.str(), "foobar10xff\n") 456 << "Unexpected createStringError() log result"; 457 458 S.flush(); 459 Msg.clear(); 460 logAllUnhandledErrors(createStringError(EC, Bar), S, ""); 461 EXPECT_EQ(S.str(), "bar\n") 462 << "Unexpected createStringError() (overloaded) log result"; 463 464 S.flush(); 465 Msg.clear(); 466 auto Res = errorToErrorCode(createStringError(EC, "foo%s", Bar)); 467 EXPECT_EQ(Res, EC) 468 << "Failed to convert createStringError() result to error_code."; 469 } 470 471 // Test that the ExitOnError utility works as expected. 472 TEST(Error, ExitOnError) { 473 ExitOnError ExitOnErr; 474 ExitOnErr.setBanner("Error in tool:"); 475 ExitOnErr.setExitCodeMapper([](const Error &E) { 476 if (E.isA<CustomSubError>()) 477 return 2; 478 return 1; 479 }); 480 481 // Make sure we don't bail on success. 482 ExitOnErr(Error::success()); 483 EXPECT_EQ(ExitOnErr(Expected<int>(7)), 7) 484 << "exitOnError returned an invalid value for Expected"; 485 486 int A = 7; 487 int &B = ExitOnErr(Expected<int&>(A)); 488 EXPECT_EQ(&A, &B) << "ExitOnError failed to propagate reference"; 489 490 // Exit tests. 491 EXPECT_EXIT(ExitOnErr(make_error<CustomError>(7)), 492 ::testing::ExitedWithCode(1), "Error in tool:") 493 << "exitOnError returned an unexpected error result"; 494 495 EXPECT_EXIT(ExitOnErr(Expected<int>(make_error<CustomSubError>(0, 0))), 496 ::testing::ExitedWithCode(2), "Error in tool:") 497 << "exitOnError returned an unexpected error result"; 498 } 499 500 // Test that the ExitOnError utility works as expected. 501 TEST(Error, CantFailSuccess) { 502 cantFail(Error::success()); 503 504 int X = cantFail(Expected<int>(42)); 505 EXPECT_EQ(X, 42) << "Expected value modified by cantFail"; 506 507 int Dummy = 42; 508 int &Y = cantFail(Expected<int&>(Dummy)); 509 EXPECT_EQ(&Dummy, &Y) << "Reference mangled by cantFail"; 510 } 511 512 // Test that cantFail results in a crash if you pass it a failure value. 513 #if LLVM_ENABLE_ABI_BREAKING_CHECKS && !defined(NDEBUG) 514 TEST(Error, CantFailDeath) { 515 EXPECT_DEATH( 516 cantFail(make_error<StringError>("foo", inconvertibleErrorCode()), 517 "Cantfail call failed"), 518 "Cantfail call failed") 519 << "cantFail(Error) did not cause an abort for failure value"; 520 521 EXPECT_DEATH( 522 { 523 auto IEC = inconvertibleErrorCode(); 524 int X = cantFail(Expected<int>(make_error<StringError>("foo", IEC))); 525 (void)X; 526 }, 527 "Failure value returned from cantFail wrapped call") 528 << "cantFail(Expected<int>) did not cause an abort for failure value"; 529 } 530 #endif 531 532 533 // Test Checked Expected<T> in success mode. 534 TEST(Error, CheckedExpectedInSuccessMode) { 535 Expected<int> A = 7; 536 EXPECT_TRUE(!!A) << "Expected with non-error value doesn't convert to 'true'"; 537 // Access is safe in second test, since we checked the error in the first. 538 EXPECT_EQ(*A, 7) << "Incorrect Expected non-error value"; 539 } 540 541 // Test Expected with reference type. 542 TEST(Error, ExpectedWithReferenceType) { 543 int A = 7; 544 Expected<int&> B = A; 545 // 'Check' B. 546 (void)!!B; 547 int &C = *B; 548 EXPECT_EQ(&A, &C) << "Expected failed to propagate reference"; 549 } 550 551 // Test Unchecked Expected<T> in success mode. 552 // We expect this to blow up the same way Error would. 553 // Test runs in debug mode only. 554 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 555 TEST(Error, UncheckedExpectedInSuccessModeDestruction) { 556 EXPECT_DEATH({ Expected<int> A = 7; }, 557 "Expected<T> must be checked before access or destruction.") 558 << "Unchecekd Expected<T> success value did not cause an abort()."; 559 } 560 #endif 561 562 // Test Unchecked Expected<T> in success mode. 563 // We expect this to blow up the same way Error would. 564 // Test runs in debug mode only. 565 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 566 TEST(Error, UncheckedExpectedInSuccessModeAccess) { 567 EXPECT_DEATH({ Expected<int> A = 7; *A; }, 568 "Expected<T> must be checked before access or destruction.") 569 << "Unchecekd Expected<T> success value did not cause an abort()."; 570 } 571 #endif 572 573 // Test Unchecked Expected<T> in success mode. 574 // We expect this to blow up the same way Error would. 575 // Test runs in debug mode only. 576 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 577 TEST(Error, UncheckedExpectedInSuccessModeAssignment) { 578 EXPECT_DEATH({ Expected<int> A = 7; A = 7; }, 579 "Expected<T> must be checked before access or destruction.") 580 << "Unchecekd Expected<T> success value did not cause an abort()."; 581 } 582 #endif 583 584 // Test Expected<T> in failure mode. 585 TEST(Error, ExpectedInFailureMode) { 586 Expected<int> A = make_error<CustomError>(42); 587 EXPECT_FALSE(!!A) << "Expected with error value doesn't convert to 'false'"; 588 Error E = A.takeError(); 589 EXPECT_TRUE(E.isA<CustomError>()) << "Incorrect Expected error value"; 590 consumeError(std::move(E)); 591 } 592 593 // Check that an Expected instance with an error value doesn't allow access to 594 // operator*. 595 // Test runs in debug mode only. 596 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 597 TEST(Error, AccessExpectedInFailureMode) { 598 Expected<int> A = make_error<CustomError>(42); 599 EXPECT_DEATH(*A, "Expected<T> must be checked before access or destruction.") 600 << "Incorrect Expected error value"; 601 consumeError(A.takeError()); 602 } 603 #endif 604 605 // Check that an Expected instance with an error triggers an abort if 606 // unhandled. 607 // Test runs in debug mode only. 608 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 609 TEST(Error, UnhandledExpectedInFailureMode) { 610 EXPECT_DEATH({ Expected<int> A = make_error<CustomError>(42); }, 611 "Expected<T> must be checked before access or destruction.") 612 << "Unchecked Expected<T> failure value did not cause an abort()"; 613 } 614 #endif 615 616 // Test covariance of Expected. 617 TEST(Error, ExpectedCovariance) { 618 class B {}; 619 class D : public B {}; 620 621 Expected<B *> A1(Expected<D *>(nullptr)); 622 // Check A1 by converting to bool before assigning to it. 623 (void)!!A1; 624 A1 = Expected<D *>(nullptr); 625 // Check A1 again before destruction. 626 (void)!!A1; 627 628 Expected<std::unique_ptr<B>> A2(Expected<std::unique_ptr<D>>(nullptr)); 629 // Check A2 by converting to bool before assigning to it. 630 (void)!!A2; 631 A2 = Expected<std::unique_ptr<D>>(nullptr); 632 // Check A2 again before destruction. 633 (void)!!A2; 634 } 635 636 // Test that handleExpected just returns success values. 637 TEST(Error, HandleExpectedSuccess) { 638 auto ValOrErr = 639 handleExpected(Expected<int>(42), 640 []() { return Expected<int>(43); }); 641 EXPECT_TRUE(!!ValOrErr) 642 << "handleExpected should have returned a success value here"; 643 EXPECT_EQ(*ValOrErr, 42) 644 << "handleExpected should have returned the original success value here"; 645 } 646 647 enum FooStrategy { Aggressive, Conservative }; 648 649 static Expected<int> foo(FooStrategy S) { 650 if (S == Aggressive) 651 return make_error<CustomError>(7); 652 return 42; 653 } 654 655 // Test that handleExpected invokes the error path if errors are not handled. 656 TEST(Error, HandleExpectedUnhandledError) { 657 // foo(Aggressive) should return a CustomError which should pass through as 658 // there is no handler for CustomError. 659 auto ValOrErr = 660 handleExpected( 661 foo(Aggressive), 662 []() { return foo(Conservative); }); 663 664 EXPECT_FALSE(!!ValOrErr) 665 << "handleExpected should have returned an error here"; 666 auto Err = ValOrErr.takeError(); 667 EXPECT_TRUE(Err.isA<CustomError>()) 668 << "handleExpected should have returned the CustomError generated by " 669 "foo(Aggressive) here"; 670 consumeError(std::move(Err)); 671 } 672 673 // Test that handleExpected invokes the fallback path if errors are handled. 674 TEST(Error, HandleExpectedHandledError) { 675 // foo(Aggressive) should return a CustomError which should handle triggering 676 // the fallback path. 677 auto ValOrErr = 678 handleExpected( 679 foo(Aggressive), 680 []() { return foo(Conservative); }, 681 [](const CustomError&) { /* do nothing */ }); 682 683 EXPECT_TRUE(!!ValOrErr) 684 << "handleExpected should have returned a success value here"; 685 EXPECT_EQ(*ValOrErr, 42) 686 << "handleExpected returned the wrong success value"; 687 } 688 689 TEST(Error, ErrorCodeConversions) { 690 // Round-trip a success value to check that it converts correctly. 691 EXPECT_EQ(errorToErrorCode(errorCodeToError(std::error_code())), 692 std::error_code()) 693 << "std::error_code() should round-trip via Error conversions"; 694 695 // Round-trip an error value to check that it converts correctly. 696 EXPECT_EQ(errorToErrorCode(errorCodeToError(errc::invalid_argument)), 697 errc::invalid_argument) 698 << "std::error_code error value should round-trip via Error " 699 "conversions"; 700 701 // Round-trip a success value through ErrorOr/Expected to check that it 702 // converts correctly. 703 { 704 auto Orig = ErrorOr<int>(42); 705 auto RoundTripped = 706 expectedToErrorOr(errorOrToExpected(ErrorOr<int>(42))); 707 EXPECT_EQ(*Orig, *RoundTripped) 708 << "ErrorOr<T> success value should round-trip via Expected<T> " 709 "conversions."; 710 } 711 712 // Round-trip a failure value through ErrorOr/Expected to check that it 713 // converts correctly. 714 { 715 auto Orig = ErrorOr<int>(errc::invalid_argument); 716 auto RoundTripped = 717 expectedToErrorOr( 718 errorOrToExpected(ErrorOr<int>(errc::invalid_argument))); 719 EXPECT_EQ(Orig.getError(), RoundTripped.getError()) 720 << "ErrorOr<T> failure value should round-trip via Expected<T> " 721 "conversions."; 722 } 723 } 724 725 // Test that error messages work. 726 TEST(Error, ErrorMessage) { 727 EXPECT_EQ(toString(Error::success()).compare(""), 0); 728 729 Error E1 = make_error<CustomError>(0); 730 EXPECT_EQ(toString(std::move(E1)).compare("CustomError {0}"), 0); 731 732 Error E2 = make_error<CustomError>(0); 733 handleAllErrors(std::move(E2), [](const CustomError &CE) { 734 EXPECT_EQ(CE.message().compare("CustomError {0}"), 0); 735 }); 736 737 Error E3 = joinErrors(make_error<CustomError>(0), make_error<CustomError>(1)); 738 EXPECT_EQ(toString(std::move(E3)) 739 .compare("CustomError {0}\n" 740 "CustomError {1}"), 741 0); 742 } 743 744 TEST(Error, Stream) { 745 { 746 Error OK = Error::success(); 747 std::string Buf; 748 llvm::raw_string_ostream S(Buf); 749 S << OK; 750 EXPECT_EQ("success", S.str()); 751 consumeError(std::move(OK)); 752 } 753 { 754 Error E1 = make_error<CustomError>(0); 755 std::string Buf; 756 llvm::raw_string_ostream S(Buf); 757 S << E1; 758 EXPECT_EQ("CustomError {0}", S.str()); 759 consumeError(std::move(E1)); 760 } 761 } 762 763 TEST(Error, ErrorMatchers) { 764 EXPECT_THAT_ERROR(Error::success(), Succeeded()); 765 EXPECT_NONFATAL_FAILURE( 766 EXPECT_THAT_ERROR(make_error<CustomError>(0), Succeeded()), 767 "Expected: succeeded\n Actual: failed (CustomError {0})"); 768 769 EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed()); 770 EXPECT_NONFATAL_FAILURE(EXPECT_THAT_ERROR(Error::success(), Failed()), 771 "Expected: failed\n Actual: succeeded"); 772 773 EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<CustomError>()); 774 EXPECT_NONFATAL_FAILURE( 775 EXPECT_THAT_ERROR(Error::success(), Failed<CustomError>()), 776 "Expected: failed with Error of given type\n Actual: succeeded"); 777 EXPECT_NONFATAL_FAILURE( 778 EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<CustomSubError>()), 779 "Error was not of given type"); 780 EXPECT_NONFATAL_FAILURE( 781 EXPECT_THAT_ERROR( 782 joinErrors(make_error<CustomError>(0), make_error<CustomError>(1)), 783 Failed<CustomError>()), 784 "multiple errors"); 785 786 EXPECT_THAT_ERROR( 787 make_error<CustomError>(0), 788 Failed<CustomError>(testing::Property(&CustomError::getInfo, 0))); 789 EXPECT_NONFATAL_FAILURE( 790 EXPECT_THAT_ERROR( 791 make_error<CustomError>(0), 792 Failed<CustomError>(testing::Property(&CustomError::getInfo, 1))), 793 "Expected: failed with Error of given type and the error is an object " 794 "whose given property is equal to 1\n" 795 " Actual: failed (CustomError {0})"); 796 EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed<ErrorInfoBase>()); 797 798 EXPECT_THAT_EXPECTED(Expected<int>(0), Succeeded()); 799 EXPECT_NONFATAL_FAILURE( 800 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), 801 Succeeded()), 802 "Expected: succeeded\n Actual: failed (CustomError {0})"); 803 804 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), Failed()); 805 EXPECT_NONFATAL_FAILURE( 806 EXPECT_THAT_EXPECTED(Expected<int>(0), Failed()), 807 "Expected: failed\n Actual: succeeded with value 0"); 808 809 EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(0)); 810 EXPECT_NONFATAL_FAILURE( 811 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), 812 HasValue(0)), 813 "Expected: succeeded with value (is equal to 0)\n" 814 " Actual: failed (CustomError {0})"); 815 EXPECT_NONFATAL_FAILURE( 816 EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(0)), 817 "Expected: succeeded with value (is equal to 0)\n" 818 " Actual: succeeded with value 1, (isn't equal to 0)"); 819 820 EXPECT_THAT_EXPECTED(Expected<int &>(make_error<CustomError>(0)), Failed()); 821 int a = 1; 822 EXPECT_THAT_EXPECTED(Expected<int &>(a), Succeeded()); 823 EXPECT_THAT_EXPECTED(Expected<int &>(a), HasValue(testing::Eq(1))); 824 825 EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(testing::Gt(0))); 826 EXPECT_NONFATAL_FAILURE( 827 EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(testing::Gt(1))), 828 "Expected: succeeded with value (is > 1)\n" 829 " Actual: succeeded with value 0, (isn't > 1)"); 830 EXPECT_NONFATAL_FAILURE( 831 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), 832 HasValue(testing::Gt(1))), 833 "Expected: succeeded with value (is > 1)\n" 834 " Actual: failed (CustomError {0})"); 835 } 836 837 TEST(Error, C_API) { 838 EXPECT_THAT_ERROR(unwrap(wrap(Error::success())), Succeeded()) 839 << "Failed to round-trip Error success value via C API"; 840 EXPECT_THAT_ERROR(unwrap(wrap(make_error<CustomError>(0))), 841 Failed<CustomError>()) 842 << "Failed to round-trip Error failure value via C API"; 843 844 auto Err = 845 wrap(make_error<StringError>("test message", inconvertibleErrorCode())); 846 EXPECT_EQ(LLVMGetErrorTypeId(Err), LLVMGetStringErrorTypeId()) 847 << "Failed to match error type ids via C API"; 848 char *ErrMsg = LLVMGetErrorMessage(Err); 849 EXPECT_STREQ(ErrMsg, "test message") 850 << "Failed to roundtrip StringError error message via C API"; 851 LLVMDisposeErrorMessage(ErrMsg); 852 853 bool GotCSE = false; 854 bool GotCE = false; 855 handleAllErrors( 856 unwrap(wrap(joinErrors(make_error<CustomSubError>(42, 7), 857 make_error<CustomError>(42)))), 858 [&](CustomSubError &CSE) { 859 GotCSE = true; 860 }, 861 [&](CustomError &CE) { 862 GotCE = true; 863 }); 864 EXPECT_TRUE(GotCSE) << "Failed to round-trip ErrorList via C API"; 865 EXPECT_TRUE(GotCE) << "Failed to round-trip ErrorList via C API"; 866 } 867 868 TEST(Error, FileErrorTest) { 869 #if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST 870 EXPECT_DEATH( 871 { 872 Error S = Error::success(); 873 consumeError(createFileError("file.bin", std::move(S))); 874 }, 875 ""); 876 #endif 877 // Not allowed, would fail at compile-time 878 //consumeError(createFileError("file.bin", ErrorSuccess())); 879 880 Error E1 = make_error<CustomError>(1); 881 Error FE1 = createFileError("file.bin", std::move(E1)); 882 EXPECT_EQ(toString(std::move(FE1)).compare("'file.bin': CustomError {1}"), 0); 883 884 Error E2 = make_error<CustomError>(2); 885 Error FE2 = createFileError("file.bin", std::move(E2)); 886 handleAllErrors(std::move(FE2), [](const FileError &F) { 887 EXPECT_EQ(F.message().compare("'file.bin': CustomError {2}"), 0); 888 }); 889 890 Error E3 = make_error<CustomError>(3); 891 Error FE3 = createFileError("file.bin", std::move(E3)); 892 auto E31 = handleErrors(std::move(FE3), [](std::unique_ptr<FileError> F) { 893 return F->takeError(); 894 }); 895 handleAllErrors(std::move(E31), [](const CustomError &C) { 896 EXPECT_EQ(C.message().compare("CustomError {3}"), 0); 897 }); 898 899 Error FE4 = 900 joinErrors(createFileError("file.bin", make_error<CustomError>(41)), 901 createFileError("file2.bin", make_error<CustomError>(42))); 902 EXPECT_EQ(toString(std::move(FE4)) 903 .compare("'file.bin': CustomError {41}\n" 904 "'file2.bin': CustomError {42}"), 905 0); 906 } 907 908 enum class test_error_code { 909 unspecified = 1, 910 error_1, 911 error_2, 912 }; 913 914 } // end anon namespace 915 916 namespace std { 917 template <> 918 struct is_error_code_enum<test_error_code> : std::true_type {}; 919 } // namespace std 920 921 namespace { 922 923 const std::error_category &TErrorCategory(); 924 925 inline std::error_code make_error_code(test_error_code E) { 926 return std::error_code(static_cast<int>(E), TErrorCategory()); 927 } 928 929 class TestDebugError : public ErrorInfo<TestDebugError, StringError> { 930 public: 931 using ErrorInfo<TestDebugError, StringError >::ErrorInfo; // inherit constructors 932 TestDebugError(const Twine &S) : ErrorInfo(S, test_error_code::unspecified) {} 933 static char ID; 934 }; 935 936 class TestErrorCategory : public std::error_category { 937 public: 938 const char *name() const noexcept override { return "error"; } 939 std::string message(int Condition) const override { 940 switch (static_cast<test_error_code>(Condition)) { 941 case test_error_code::unspecified: 942 return "An unknown error has occurred."; 943 case test_error_code::error_1: 944 return "Error 1."; 945 case test_error_code::error_2: 946 return "Error 2."; 947 } 948 llvm_unreachable("Unrecognized test_error_code"); 949 } 950 }; 951 952 static llvm::ManagedStatic<TestErrorCategory> TestErrCategory; 953 const std::error_category &TErrorCategory() { return *TestErrCategory; } 954 955 char TestDebugError::ID; 956 957 TEST(Error, SubtypeStringErrorTest) { 958 auto E1 = make_error<TestDebugError>(test_error_code::error_1); 959 EXPECT_EQ(toString(std::move(E1)).compare("Error 1."), 0); 960 961 auto E2 = make_error<TestDebugError>(test_error_code::error_1, 962 "Detailed information"); 963 EXPECT_EQ(toString(std::move(E2)).compare("Error 1. Detailed information"), 964 0); 965 966 auto E3 = make_error<TestDebugError>(test_error_code::error_2); 967 handleAllErrors(std::move(E3), [](const TestDebugError &F) { 968 EXPECT_EQ(F.message().compare("Error 2."), 0); 969 }); 970 971 auto E4 = joinErrors(make_error<TestDebugError>(test_error_code::error_1, 972 "Detailed information"), 973 make_error<TestDebugError>(test_error_code::error_2)); 974 EXPECT_EQ(toString(std::move(E4)) 975 .compare("Error 1. Detailed information\n" 976 "Error 2."), 977 0); 978 } 979 980 } // namespace 981