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