27da94f9e9a01ed64dc069e0e0a3c214d549f399
[folly.git] / folly / test / ExceptionWrapperTest.cpp
1 /*
2  * Copyright 2014 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <gtest/gtest.h>
18 #include <stdexcept>
19 #include "folly/ExceptionWrapper.h"
20
21 using namespace folly;
22
23 // Tests that when we call throwException, the proper type is thrown (derived)
24 TEST(ExceptionWrapper, throw_test) {
25   std::runtime_error e("payload");
26   auto ew = make_exception_wrapper<std::runtime_error>(e);
27
28   std::vector<exception_wrapper> container;
29   container.push_back(ew);
30
31   try {
32     container[0].throwException();
33   } catch (std::runtime_error& e) {
34     std::string expected = "payload";
35     std::string actual = e.what();
36     EXPECT_EQ(expected, actual);
37   }
38 }
39
40 TEST(ExceptionWrapper, boolean) {
41   auto ew = exception_wrapper();
42   EXPECT_FALSE(bool(ew));
43   ew = make_exception_wrapper<std::runtime_error>("payload");
44   EXPECT_TRUE(bool(ew));
45 }
46
47 TEST(ExceptionWrapper, try_and_catch_test) {
48   std::string expected = "payload";
49
50   // Catch rightmost matching exception type
51   exception_wrapper ew = try_and_catch<std::exception, std::runtime_error>(
52     [=]() {
53       throw std::runtime_error(expected);
54     });
55   EXPECT_TRUE(ew.get());
56   EXPECT_EQ(ew.get()->what(), expected);
57   auto rep = dynamic_cast<std::runtime_error*>(ew.get());
58   EXPECT_TRUE(rep);
59
60   // Changing order is like catching in wrong order. Beware of this in your
61   // code.
62   auto ew2 = try_and_catch<std::runtime_error, std::exception>([=]() {
63     throw std::runtime_error(expected);
64   });
65   EXPECT_TRUE(ew2.get());
66   // We are catching a std::exception, not std::runtime_error.
67   EXPECT_NE(ew2.get()->what(), expected);
68   rep = dynamic_cast<std::runtime_error*>(ew2.get());
69   EXPECT_FALSE(rep);
70
71   // Catches even if not rightmost.
72   auto ew3 = try_and_catch<std::exception, std::runtime_error>([]() {
73     throw std::exception();
74   });
75   EXPECT_TRUE(ew3.get());
76   EXPECT_NE(ew3.get()->what(), expected);
77   rep = dynamic_cast<std::runtime_error*>(ew3.get());
78   EXPECT_FALSE(rep);
79
80   // If does not catch, throws.
81   EXPECT_THROW(
82     try_and_catch<std::runtime_error>([]() {
83       throw std::exception();
84     }),
85     std::exception);
86 }