Wednesday, April 14, 2010

System error support in C++0x - part 5

[ part 1, part 2, part 3, part 4 ]

Creating your own error conditions

User-extensibility in the <system_error> facility is not limited to error codes: error_condition permits the same customisation.

Why create custom error conditions?

To answer this question, let's revisit the distinction between error_code and error_condition:

  • class error_code - represents a specific error value returned by an operation (such as a system call).
  • class error_condition - something that you want to test for and, potentially, react to in your code.

This suggests some use cases for custom error conditions:

  • Abstraction of OS-specific errors.

    Let's say you're writing a portable wrapper around getaddrinfo(). Two interesting error conditions are the tentative "the name does not resolve at this time, try again later", and the authoritative "the name does not resolve". The getaddrinfo() function reports these errors as follows:

    • On POSIX platforms, the errors are EAI_AGAIN and EAI_NONAME, respectively. The error values are in a distinct "namespace" to errno values. This means you will have to implement a new error_category to capture the errors.
    • On Windows, the errors are WSAEAI_AGAIN and WSAEAI_NONAME. Although the names are similar to the POSIX errors, they share the GetLastError "namespace". Consequently, you may want to reuse std::system_category() to capture and represent getaddrinfo() errors on this platform.

    To avoid discarding information, you want to preserve the original OS-specific error code while providing two error conditions (called name_not_found_try_again and name_not_found, say) that API users can test against.

  • Giving context-specific meaning to generic error codes.

    Most POSIX system calls use errno to report errors. Rather than define new errors for each function, the same errors are reused and you may have to look at the corresponding man page to determine the meaning. If you implement your own abstractions on top of these system calls, this context is lost to the user.

    For example, say you want to implement a simple database where each entry is stored in a separate flat file. When you try to read an entry, the database calls open() to access the file. This function sets errno to ENOENT if the file does not exist.

    As the database's storage mechanism is abstracted from the user, it could be surprising to ask them to test for no_such_file_or_directory. Instead, you can create your own context-specific error condition, no_such_entry, which is equivalent to ENOENT.

  • Testing for a set of related errors.

    As your codebase grows, you might find the same set of errors are checked again and again. Perhaps you need to respond to low system resources:

    • not_enough_memory
    • resource_unavailable_try_again
    • too_many_files_open
    • too_many_files_open_in_system
    • ...

    in several places, but the subsequent action differs at each point of use. This shows that there is a more general condition, "the system resources are low", that you want to test for and react to in your code.

    A custom error condition, low_system_resources, can be defined so that its equivalence is based on a combination of other error conditions. This allows you to write each test as:

    if (ec == low_system_resources)
    ...

    and so eliminate the repetition of individual tests.

The definition of custom error conditions is similar to the method for error_codes, as you will see in the steps below.

Step 1: define the error values

You need to create an enum for the error values, similar to std::errc:

enum class api_error
{
low_system_resources = 1,
...
name_not_found,
...
no_such_entry
};

The actual values you use are not important, but you must ensure that they are distinct and non-zero.

Step 2: define an error_category class

An error_condition object consists of both an error value and a category. To create a new category, you must derive a class from error_category:

class api_category_impl
: public std::error_category
{
public:
virtual const char* name() const;
virtual std::string message(int ev) const;
virtual bool equivalent(
const std::error_code& code,
int condition) const;
};

Step 3: give the category a human-readable name

The error_category::name() virtual function must return a string identifying the category:

const char* api_category_impl::name() const
{
return "api";
}

Step 4: convert error conditions to strings

The error_category::message() function converts an error value into a string that describes the error:

std::string api_category_impl::message(int ev) const
{
switch (ev)
{
case api_error::low_system_resources:
return "Low system resources";
...
}
}

However, depending on your use case, it may be unlikely that you'll ever call error_condition::message(). In that case, you can take a shortcut and simply write:

std::string api_category_impl::message(int ev) const
{
return "api error";
}

Step 5: implement error equivalence

The error_category::equivalent() virtual function is used to define equivalence between error codes and conditions. In fact, there are two overloads of the error_category::equivalent() function. The first:

virtual bool equivalent(int code,
const error_condition& condition) const;

is used to establish equivalence between error_codes in the current category with arbitrary error_conditions. The second overload:

virtual bool equivalent(
const error_code& code,
int condition) const;

defines equivalence between error_conditions in the current category with error_codes from any category. Since you are creating custom error conditions, it is the second overload that you must override.

Defining equivalence is simple: return true if you want an error_code to be equivalent to your condition, otherwise return false.

If your intent is to abstract OS-specific errors, you might implement error_category::equivalent() like this:

bool api_category_impl::equivalent(
const std::error_code& code,
int condition) const
{
switch (condition)
{
...
case api_error::name_not_found:
#if defined(_WIN32)
return code == std::error_code(
WSAEAI_NONAME, system_category());
#else
return code = std::error_code(
EAI_NONAME, getaddrinfo_category());
#endif
...
default:
return false;
}
}

(Obviously getaddrinfo_category() needs to be defined somewhere too.)

The tests can be as complex as you like, and can even reuse other error_condition constants. You may want to do this if you're creating a context-specific error condition, or testing for a set of related errors:

bool api_category_impl::equivalent(
const std::error_code& code,
int condition) const
{
switch (condition)
{
case api_error::low_system_resources:
return code == std::errc::not_enough_memory
|| code == std::errc::resource_unavailable_try_again
|| code == std::errc::too_many_files_open
|| code == std::errc::too_many_files_open_in_system;
...
case api_error::no_such_entry:
return code == std::errc::no_such_file_or_directory;
default:
return false;
}
}

Step 6: uniquely identify the category

You should provide a function to return a reference to a category object:

const std::error_category& api_category();

such that it always returns a reference to the same object. As with custom error codes, you can use a global:

api_category_impl api_category_instance;

const std::error_category& api_category()
{
return api_category_instance;
}

or you can make use of C++0x's thread-safe static variables:

const std::error_category& api_category()
{
static api_category_impl instance;
return instance;
}

Step 7: construct an error_condition from the enum

The <system_error> implementation requires a function called make_error_condition() to associate an error value with a category:

std::error_condition make_error_condition(api_error e)
{
return std::error_condition(
static_cast<int>(e),
api_category());
}

For completeness, you should also provide the equivalent function for construction of an error_code. I'll leave that as an exercise for the reader.

Step 8: register for implicit conversion to error_condition

Finally, for the api_error enumerators to be usable as error_condition constants, enable the conversion constructor using the is_error_condition_enum type trait:

namespace std
{
template <>
struct is_error_condition_enum<api_error>
: public true_type {};
}

Using the error conditions

The api_error enumerators can now be used as error_condition constants, just as you may use those defined in std::errc:

std::error_code ec;
load_resource("http://some/url", ec);
if (ec == api_error::low_system_resources)
...

As I've said several times before, the original error code is retained and no information is lost. It doesn't matter whether that error code came from the operating system or from an HTTP library with its own error category. Your custom error conditions can work equally well with either.

Next, in what will probably be the final instalment, I'll discuss how to design APIs that use the <system_error> facility.

436 comments:

  1. Hi Chris, thanks for this serie of articles!

    This was really helpfull!

    Great blog! Nice and impresive work!

    Thanks, I've learned so many things about asynchronous thinking and programming!

    What about URDL :)? This seems to be a great an usefull application of ASIO. And what about your book? ;)

    Once again : thanks for your work! Very helpfull.

    ReplyDelete
  2. Your blog series is amazing! Please, continue :-)

    ReplyDelete
  3. Hi Chris, great series, I was looking forward to the API entry. This is a great intro.

    ReplyDelete
  4. Hi Chris. Playing with clang I came across an error ? It seems related to something that crept into the standard late. This affects the steps involving 'defining and declaring' non user defined types in std::.

    The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

    ReplyDelete
  5. I just came across this, this also causes asio to fail as it uses signals2 and there is a problem with forward declarations. This is fixed in boost svn though.

    http://stackoverflow.com/questions/9576112/implicit-instantiation-of-undefined-template-boost-bug-or-clang-bug

    ReplyDelete
  6. It seems that there is a minor typo in the getaddrinfo_category example: the assignment operator should be replaced by equality comparison operator.

    BEFORE:

    return code = std::error_code(
    EAI_NONAME, getaddrinfo_category());

    AFTER:

    return code == std::error_code(
    EAI_NONAME, getaddrinfo_category());

    ReplyDelete
  7. Hi Chris, please finish the series! We are still waiting.

    ReplyDelete
  8. Do you have the complete working code for this?

    ReplyDelete
  9. How would std::error_code handle an error that includes not just an error code but also a message from the remote system?

    ReplyDelete
  10. Thanks for the great article! If you are in search of a great software development company, check Softvelopers. Company has 17+ years of field experience in software development.

    ReplyDelete
  11. That is a really good article. I would like to add that sometimes if you want to get a proper product done it is better to contact a software development company with high proficiency in this. I would recommend the EffectiveSoftcompany.

    ReplyDelete
  12. Thanks for sharing such information! It may come to your mind that it's better to turn a software development company...then
    iTechArt will help you I guess. At least their expertise is a match.

    ReplyDelete
  13. Does anybody mind, if I ask? Where is the next post, on "how to design API's" to use this?

    ReplyDelete
  14. Hire php developers – Save cost by hiring dedicated PHP developers & PHP programmer from this site.

    ReplyDelete
  15. The blog you have shared is incredibly helpful. The tips you have shared related to web development is really informative. Thanks for sharing this blog!
    Hire Dedicated Opencart Developers
    Hire Dedicated Magento Developer
    Hire Dedicated Web Developers
    Hire Dedicated Developers
    Hire Cake Php Developer

    ReplyDelete
  16. In the competitive market finding the best outsourcing services is a challenging task. This post helps me to find the best one. Thanks for sharing this post.
    Hire a Programmer
    Mobile App Development India
    Hire Wordpress Developer
    Hire Opencart Developer
    Hire Php Programmer

    ReplyDelete
  17. I have read your article, it is very informative and helpful for me.I admire the valuable information you offer in your articles. Thanks for posting it..

    tree trimmers palm beach county

    ReplyDelete
  18. I think this is one of the most significant information for me. And i’m glad reading your article. But should remark on some general things, The web site style is perfect, the articles is really great : D. Good job, cheers
    fire restoration services broward county

    ReplyDelete
  19. Hi, This is nice article you shared great information i have read it thanks for giving such a wonderful Blog for reader.
    water heater installation minneapolis

    ReplyDelete
  20. This is a great article thanks for sharing this informative information. I will visit your blog regularly for some latest posts
    fire restoration companies fort lauderdale

    ReplyDelete
  21. I think this is one of the most significant information for me. And i’m glad reading your article. But should remark on some general things, The web site style is perfect, the articles is really great : D. Good job, cheers.
    remodeling contractors clearfield ut

    ReplyDelete
  22. Thanks for a wonderful share. Your article has proved your hard work and experience you have got in this field. Brilliant .i love it reading.
    stamped concrete driveway fort lauderdale

    ReplyDelete
  23. Thanks for sharing the great article on this topic.
    Jonathan Dax Cooke

    ReplyDelete
  24. Superbly written article, if only all bloggers offered the same content as you, the internet would be a far better place.
    bathroom remodeling ogden ut

    ReplyDelete
  25. Great article and a nice way to promote online. I’m satisfied with the information that you provided
    concrete stamping company broward county

    ReplyDelete
  26. הייתי חייבת לפרגן, תודה על השיתוף.
    חברת קבוצת גבאי

    ReplyDelete
  27. This comment has been removed by the author.

    ReplyDelete
  28. סופסוף מישהו שתואם לדעותיי בנושא. תודה.
    תכשיטי אפולו

    ReplyDelete
  29. מזל שנתקלתי בכתבה הזאת. בדיוק בזמן
    מגשי אירוח

    ReplyDelete
  30. הייתי חייבת לפרגן, תודה על השיתוף.
    שולחן עגול נפתח

    ReplyDelete
  31. תמשיכו בפרסום פוסטים מעניינים כמו זה. תודה.
    טיפול קוסמטי לפנים

    ReplyDelete
  32. כל מילה. תודה על השיתוף, מחכה לעוד פוסטים בנושא.
    אטרקציות לחתונות

    ReplyDelete
  33. go123movies
    Best free streaming movies sites: Movies are the great entertainment part of our life. Not just for entertainment purposes also it influences our living greatly. Yes, there are millions of good movies to watch in our free time with family and friends. Besides watching movies on TV and at the theaters, watch free streaming movies online from free movie sites have become popular.

    ReplyDelete
  34. מעולה. תודה על הכתיבה היצירתית.
    ברוקרים

    ReplyDelete
  35. Great Information,it has lot for stuff which is informative.I will share the post with my friend
    playboy bunny necklace

    ReplyDelete
  36. אין ספק שהפוסט הזה דורש שיתוף. תודה.
    הדפסה על עץ

    ReplyDelete
  37. Thanks for sharing this nice informatione!
    financial modelling to give you confidence in your financial strategy and provide business valuations.

    ReplyDelete
  38. Want sexy and hot moments in popular Hong Kong Escort, Give your life lovely time, Want more fun with escort girls.

    ReplyDelete
  39. Download your favorite Latest Mp3 Lyrics which are available in English, Hindi, Bangla, Telugu, Latin, Arabic, Russian, etc.

    Click Here

    Click Here

    Click Here

    Click Here

    Click Here

    ReplyDelete
  40. Wow! Very informative blog. I visits lots of blog but this blog is very unique. Thanks
    CMD368

    ReplyDelete
  41. Thanks for the information. This is a very informative post. Plaisio Computer SA provide a stock quote, history, news and other vital information to help you with your stock trading. It is a Greece-based company that assembles and trades personal computers telecommunication.

    ReplyDelete
  42. Wonderful share by the author. I found this blog helps me a lot.
    Good Night Romantic images

    ReplyDelete
  43. Thanks for your sharing! The information your share is very useful to me and many people are looking for them just like me!


    We have collection of best 2020 sex doll to fulfill your desire, so if you need realistic female sex dolls then Love Doll Palace is largest online store for you , who are providing young love doll for you, these are made by silicone and TPE, which will give you full happiness at sex duration and you can enjoy with her at any position.

    ReplyDelete
  44. Choose the right lawyer to defend you. The New York Criminal Defense Attorneys at Abe George Lawyer Law Group handle different types of crimes in NewYork. So if you need then abe george lawyer is one of the best for you!!

    Abe George and Lawyer

    Abe George and Lawyer

    Abe George and Lawyer
    Abe George Lawyer
    Abe George Lawyer
    Abe George and Lawyer
    Abe George and Lawyer

    ReplyDelete
  45. כל מילה. תודה על השיתוף, מחכה לעוד פוסטים בנושא.
    חברת קידום אתרים

    ReplyDelete

  46. Meet Abe George Lawyer recognized as the best criminal defense attorney to protect your rights and handles entire crucial situations of yours and your family.
    He is a highly experienced executor, who serves the excellent defendant assistances with his potential methodology to come you out from the crime obligations
    efficiently.
    abe george lawyer
    abe george lawyer
    abe george lawyer

    ReplyDelete
  47. כתיבה מעולה, אהבתי. אשתף עם העוקבים שלי.
    מזרון למיטת תינוק

    ReplyDelete

  48. Thanks For Sharing this Information!!
    If you are getting issue login to orbi Router. Then use www.orbilogin.net. It enables the user to connect to orbi device with
    ease.

    ReplyDelete
  49. פוסט נחמד. חייב לשתף עם העוקבים שלי.
    עיצוב ממשק משתמש

    ReplyDelete
  50. Fantastic piece, well tailored…. You sort of cleared my phobias… Now I can give it a shot… I pray I don’t run out of contents!…a big kudos

    gyn services brooklyn
    smp seattle
    bathroom remodel near me
    hvac near me
    vinyl siding repairin summerville sc
    wedding dj columbia sc

    ReplyDelete
  51. Get the support for www.routerlogin.net routers, extenders, modems, and cameras and other popular devices manufactured by the Netgear.

    ReplyDelete
  52. Never experienced this error before, I will get solution form Los Angeles Wordpress Developer

    ReplyDelete
  53. Hire any of these c++ development companies I am sure they be able to sort this c++ error for you. All the companies listed have top c++ developers.

    ReplyDelete
  54. your artical is very great i regularly visit your website you can also visist my website my website url is https://letestnews.co.in/


    letestnews

    ReplyDelete
  55. This is a great article thanks for sharing this informative information.
    אינטרקום לדלת כניסה

    ReplyDelete
  56. what a great style, it not easy job well don.


    Bastion Balance Seoul

    ReplyDelete
  57. Congratulations you guys, nice couple, have fun.


    Investors Magazine

    ReplyDelete
  58. I have a project that I'm simply now working on, and I have been at the
    glance out for such information
    IB Global Academy

    ReplyDelete
  59. I found your blog very informative and really well written. otsakre for your good effort you've put in. Visit me for Router tech support. 24/7 Chat Assistance for complex Routers issues. Call me for Assistance 9177320091 Visit me for making good relations. Thanks.
    http://orbiloginn.com
    https://www.linksysmarrtwifi.com
    https://myarloo.com/ http://www.routersynologyy.com https://routerloglogin.com

    Orbi Login
    Arlo Login
    Linksyssmartwifi com
    find Synology
    Routerlogin

    ReplyDelete
  60. מרתק כמה שלא הבנתי כלום עד שקראתי את המאמר הנפלא הזה

    בניית בריכת שחייה מבטון

    ReplyDelete
  61. Great lovely arrangements looks traditional wedding.


    Garage Door Repair Calgary

    ReplyDelete
  62. I am a Staff Author at FieldEngineer.com a Marketplace for On-Demand telecom workforce, extending from field engineers to high-level network engineers, project managers and Network Architects in 146 nation

    Soa security

    ReplyDelete
  63. מעניין מאוד, למרות שלא הכל מדויק לדעתי
    רכב במימון מלא ללא מקדמה

    ReplyDelete
  64. תודה על השיתוף, מאוד מעניין
    עקירה כירורגית

    ReplyDelete
  65. חשבתי שאתקל בסתם עוד מאמר שטחי. טעיתי.
    שמות כלבים

    ReplyDelete
  66. Lovely pictures, awesome these are looking so romantic and locations are great.


    garage door opener repair pittsburgh

    ReplyDelete
  67. Thanks a lot for sharing a piece of wonderful information
    Guys Fix It Mag

    ReplyDelete
  68. Thank you for the helpful post. I found your blog with Google and I will start following. Hope to see new blogs soon.


    dishwasher repair mississauga

    ReplyDelete
  69. Thanks for sharing this unique and informative content.
    garage door repair chestermere

    ReplyDelete
  70. Ideas! i think no need of any ideas just get to gather and start having fun, chit chat and other activities.


    garage door repair vancouver

    ReplyDelete
  71. Nice idea, i am gonna try the same for my web site. thanks.


    Garage Door Repair Doctors

    ReplyDelete
  72. Nice service there are just few who are providing this service great job.


    Los Angeles Garage Door Repair

    ReplyDelete
  73. אני לא מסכים עם כל מה שכתוב, אבל מאמר מעניין מאוד


    אשראי מסחרי

    ReplyDelete
  74. לא כל כך מסכים עם הכל כאן האמת.

    התקנת אינטרקום

    ReplyDelete
  75. Wow!, thanks for sharing your ideas and especially for giving us priced features information. I love the way you balanced your views by still advocating. Well, for those of us that are still growing and does not have money to lose, your blog is really informative and helpful.

    Regards,
    Online Dissertation Help

    ReplyDelete
  76. Great article nice pictures and different concept for me i didn't know about this way of making wish.


    silvergaragedoors.ca

    ReplyDelete
  77. I simply wanted to write down a fast word to mention you for those wonderful tips and hints you’re showing on this site dg casino



    ReplyDelete
  78. Cool blog you got here and thank you for the valuable info.


    Garage Door Installation Calgary

    ReplyDelete
  79. One of the best sites i have visited in last few weeks and i would love to be the part of your emerging community!
    먹튀검증업체

    ReplyDelete
  80. It’s really great post, nice blog..I would like to appreciate your work and would like to tell to my friends.


    garage door cable repair

    ReplyDelete
  81. Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog.Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog.


    garage door repair

    ReplyDelete
  82. I will be honest these is the most useful tips I have read till date. Thanks for putting all this together. As a newbie blogger, I am going through different stages of learning and all ups and downs what a normal newbie blogger face. But the most important thing I am not giving up and holding it until I find success. I am really positive using your thoughts and knowledge will help me to improve myself. Siberian husky Puppies Breeders      Great work. Keep doing this great work for us. Loved it.

    ReplyDelete
  83. You have got some great posts in your blog. Keep up with the good work.


    garage door repair Cambridge

    ReplyDelete
  84. I really loved reading your thoughts, obviously you know what are you talking about! Your site is so easy to use too, I’ve bookmark it in my folder


    garage door repair North York 

    ReplyDelete
  85. אני לא מסכים עם כל מה שכתוב, אבל מאמר מעניין מאוד

    חברת ניקיון בצפון

    ReplyDelete
  86. I really love your weblog, Its great to find not absolutely everyone is just posting a ton of rubbish these days!

    בר מתוקים

    ReplyDelete
  87. Nice service there are just few who are providing this service great job.
    Finance Magazine

    ReplyDelete
  88. This discussion unexpectedly takes my attention to join inside. Well, after I read all of them, it gives me new idea for my blog. thanks



    duct cleaning pittsburgh 




    ReplyDelete
  89. I have been reading your posts regularly. I need to say that you are doing a fantastic job. Please keep up the great work.

    Garage Door Doctor

    ReplyDelete
  90. Amazing article...Thanks for sharing....
    Nio Stars Technologies LLP is a best Digital Marketing Company in Pune. We offering all Digital Marketing Services like SEO, SEM, SMO, SEM, Online Advertising,Email Marketing. We provide 24/7 Services for you.

    ReplyDelete
  91. Attractive, post. I just stumbled upon Your weblog and wanted to say that I have liked browsing your blog posts. After all, I will surely subscribe to your feed,
    and I hope you will write again soon!
    I felt very happy while reading this site. This was really very informative site for me. I really liked it. This was really a cordial post.
    Thanks a lot!.
    jav

    ReplyDelete
  92. מאמר ממש מרשים תודה רבה על כל המידע המקצועי
    שתלים דנטליים

    ReplyDelete
  93. We are really grateful for your blog post. You will find a lot of approaches after visiting your post. I was exactly searching for. Thanks for such post and please keep it up. Great work. polyurea

    ReplyDelete
  94. Great thank you article for all the comprehensive information

    בבורגס

    ReplyDelete

  95. I wanted to point out that a really professional article thank you so much for all the content
    חשיבות של עיצוב אתר מנעולן

    ReplyDelete
  96. I was browsing the internet for information and found your blog. I am impressed with the information you 토토사이트

    ReplyDelete
  97. For no reason knew that opinions could be this varied. Thanks for all the enthusiasm to offer 먹튀검증

    ReplyDelete
  98. Thank you for sharing your issue. Here are Few Hostinger Coupon Code.

    ReplyDelete
  99. This is a wonderful article, Given so much info in it, These type of articles keeps the user's interest in the website.
    garage door replacement north dallas

    ReplyDelete
  100. Enjoyed reading the article above, really explains everything in detail, the article is very interesting and effective. Thank you and good luck with the upcoming articles...For more please visit: Mobile App Development India

    ReplyDelete
  101. We promise to do our This is a pure nice post.Plz answer back as I’m looking to construct 꽁머니

    ReplyDelete
  102. my own blog and would like to find out where u got this from Your post has really helped me a lot. 안전사이트

    ReplyDelete
  103. It's always exciting to read articles from other writers and practice something from their websites.
    window replacement

    ReplyDelete
  104. Spot on with this article, I really think this website needs more attention. I'll probably be back to read more, thanks for the info.


    Stamford Garage Doors

    ReplyDelete
  105. Spot on with this article, I really think this website needs more attention. I'll probably be back to read more, thanks for the info.


    24-hour garage door repair in Las Vegas

    ReplyDelete
  106. Web Hosting Affiliate Programs, web hosting affiliate programs in india, affiliate programs for web hosting, affiliate programs hosting hostinger coupon code india, Hotels , web hosting, bluehost affiliate program, affiliate program web hosting, affiliate program web

    ReplyDelete
  107. 코로나 락다운 대한항공 조현아 빅뱅승리 메이저놀이터 목록 아이유 바퀴달린집 키노사다리하는법 추천토토 실시간배팅 MGM승률 토토사이트목록
    I recommend a Toto site that has been verified for safe use. 토토사이트 If you ask VIP Toto, I promise to recommend a safety playground. 안전토토사이트We promise to recommend the Toto site that is safer than anyone else, 토토 and please contact VIP Toto for a major safety playground that you can trust and use. 스포츠토토

    ReplyDelete
  108. Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog.Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog.


    San Francisco Garage Door Repair

    ReplyDelete
  109. So lucky to come across your excellent blog. Your blog brings me a great deal of fun. Good luck with the site.
    commercial real estate website design

    ReplyDelete
  110. I am really very agree with your qualities it is very helpful for look like home. Thanks so much for info and keep it up.


    window replacement

    ReplyDelete
  111. I am really very agree with your qualities it is very helpful for look like home. Thanks so much for info and keep it up.


    garage door motor repair

    ReplyDelete
  112. I am really very agree with your qualities it is very helpful for look like home. Thanks so much for info and keep it up.


    central air conditioning

    ReplyDelete
  113. I am really very agree with your qualities it is very helpful for look like home. Thanks so much for info and keep it up.


    Kitchen Star Houston

    ReplyDelete
  114. I am really very agree with your qualities it is very helpful for look like home. Thanks so much for info and keep it up.


    garage door cable repair

    ReplyDelete
  115. A very awesome blog post. We are really grateful for your blog post. You will find a lot of approaches after visiting your post.
    dentist solvang

    ReplyDelete
  116. This is a wonderful article, Given so much info in it, These type of articles keeps the user's interest in the website.
    ------------
    [url=https://www.livingyourawesome.com/post/i-feel-like-a-failure]feeling like a failure[/url]

    ReplyDelete
  117. Excellent article. The writing style which you have used in this article is very good and it made the article of better quality.
    cash value life insurance

    ReplyDelete
  118. I am really very agree with your qualities it is very helpful for look like home. Thanks so much for info and keep it up.


    scam

    ReplyDelete
  119. This is a wonderful article, Given so much info in it, These type of articles keeps the user's interest in the website.
    stratford management scam

    ReplyDelete
  120. Spot on with this article, I really think this website needs more attention. I'll probably be back to read more, thanks for the info.


    Google auto complete

    ReplyDelete
  121. NO BLAME. NO SHAME. You have tax issues, and it’s our job to solve them. We’ll develop a strategy you can manage and negotiate with the taxing authorities on your behalf.

    tax solution

    ReplyDelete
  122. Hi there, I just wanted to say thanks for this informative post, can you please allow me to post it on my blog?


    Baby dressing

    ReplyDelete
  123. yes it happens with me as well. we feel the difference, convince and comfort. but how ever we are not simple free of worries as these old people were.nice article.


    biofit supplement reviews

    ReplyDelete
  124. เล่นสล็อตและก็เกมแจ็คพอตที่น่าตื่นตาตื่นใจที่ AKASLOT
    ตรวจคอลเลกชั่น pgslot รวมทั้งเกมที่นานาประการแล้วก็นานาประการของพวกเรา คุณจะศึกษาค้นพบภาพที่งดงาม การเล่นเกมที่สมจริงสมจัง และก็จังหวะที่จะชนะรางวัลแจ็คพอตสุดดีเลิศ ตัวเลือกไม่จบไม่สิ้น ตั้งแต่เกมเริ่มแรกของ Grosvenor Casinos รวมทั้ง Tiki Runner และก็ Atlantis Megaways ไปจนกระทั่งเกมใหม่แล้วก็พิเศษสุดตื่นเต้น ยกตัวอย่างเช่น pgslot คุณมั่นใจว่าจะได้เจอกับเกมที่จะทำให้ท่านเพลิน
    เพลิดเพลินเจริญใจกับลักษณะพิเศษตั้งแต่ฟรีสปินแล้วก็เกมโบนัสไปจนกระทั่งแจ็คพอตรายวันรวมทั้งการแลกเปลี่ยนเครื่องหมาย ตลอดจนการชำระเงินสูงสุด 250,000 ปอนด์สำหรับเกมที่ไม่ใช่แจ็คพอตเพียงแค่นั้น รับข้อมูลทั้งหมดทั้งปวงเกี่ยวกับสล็อตแจ็คพอตรวมทั้งเกมที่มีให้ที่ pgslot จาก AKASLOT
    เล่นสล็อตออนไลน์ที่ AKASLOT
    ถ้าเกิดคุณพึ่งสมัครสมาชิกกับ AKASLOT ช่องทางที่คุณกำลังปรารถนาเล่นสล็อตออนไลน์หรือ pgslot ด้วยแบบอย่างที่เรียบง่ายรวมทั้งคุณลักษณะที่บันเทิงใจ pgslot ออนไลน์มอบประสบการณ์การเล่นเกมที่บรรเทาแล้วก็บีบคั้นต่ำ มีเกมให้เลือกมากพร้อมธีมนานาประการตั้งแต่อียิปต์โบราณรวมทั้ง Lucky Leprechauns ไปจนกระทั่งภาพยนตร์ฮอลลีวูดแล้วก็รายการทีวี แต่ละเกมมีข้อเสนอแนะของตนเอง ด้วยเหตุผลดังกล่าวแม้คุณจะไม่เคยเล่นสล็อตออนไลน์มาก่อน คุณก็จะเข้าจิตใจได้อย่างเร็วว่าควรจะมองหาเครื่องหมายใดและก็ช่องชำระเงินดำเนินการเช่นไร pgslot ออนไลน์ไม่น้อยเลยทีเดียวมีรอบหมุนฟรีซึ่งคุณสามารถหมุนวงล้อโดยไม่ต้องพนันเงินสดรวมทั้งคุณลักษณะที่น่าตื่นตาตื่นใจที่ให้ท่านเป็นไปได้มากขึ้นที่จะชนะรางวัลเงินสด

    แนวทางเล่นสล็อตออนไลน์
    ด้วยเหตุดังกล่าวคุณเล่น pgslot ออนไลน์ยังไง เกมสล็อตเกือบจะทั้งหมดมีคำเสนอแนะรากฐานแบบเดียวกัน เพียงแค่คลิกปุ่มหมุนแล้วเกมจะจัดแจงที่เหลือ
    เกม pgslot ไม่ได้อยากความสามารถหรือกลอุบายอะไรก็ตามด้วยเหตุว่าชัยขึ้นกับช่องทาง สล็อตออนไลน์ก็เลยเย้ายวนใจผู้เล่นทุกระดับ

    ช่องชำระเงินเกมสล็อต
    เพื่อชนะ คุณจำต้องจับคู่เครื่องหมายที่เช่นกันในลำดับเฉพาะบนวงล้อ นี่เรียกว่าเพย์ไลน์หรือวินไลน์ แต่ละเกมจะมีปริมาณช่องชำระเงินที่ไม่เหมือนกัน คุณสามารถมองว่าสิ่งพวกนี้เป็นยังไงในแต่ละรายการอาหารช่วยเหลือในเกม เพย์ไลน์ชอบ:
    เป็นระเบียบเรียบร้อย
    ในต้นแบบสิกข์แซก
    เป็นรูปตัววี
    แนวเฉียง

    เครื่องหมายที่ชนะในแต่ละเกมจะนาๆประการ และก็ช่องชำระเงินจะมีน้ำหนักนาๆประการในแต่ละสปิน เมื่อคุณเล่นด้วยเงินจริง ยอดเงินของคุณจะถูกหักเมื่อใดก็ตามคุณหมุนวงล้อ คุณควรต้องตกลงใจว่าจะวางเดิมพันในแต่ละเพย์ไลน์มากมายน้อยแค่ไหนเพื่อประกอบเป็นเงินที่ใช้ในการเดิมพันทั้งสิ้นของคุณ
    ซึ่งแน่ๆว่าการเล่นเกมสล็อตหรือ pgslot ออนไลน์ สำหรับช่องบางช่องมิได้ใช้ช่องชำระเงินรวมทั้งชำระเงินตามปริมาณเครื่องหมายที่คุณวางบนวงล้อแทน ด้วยเกมชนิดนี้ คุณสามารถมีแนวทางชนะมากยิ่งกว่า 2,000 แนวทาง เกม Megaways พรีเซ็นท์ความมากมายหลายมากขึ้นเรื่อยๆด้วยสูงถึง 117,649 แนวทางสำหรับเพื่อการชนะ!

    ReplyDelete
  125. I am really very agree with your qualities it is very helpful for look like home. Thanks so much for info and keep it up.


    appliancemississauga.com

    ReplyDelete
  126. I am really very agree with your qualities it is very helpful for look like home. Thanks so much for info and keep it up.


    scam

    ReplyDelete
  127. If you are thinking of buying new vanities for your home then don't look further than NZHomeware. NZHomeware is a well-known company that can help you with the best quality and branded bathroom accessories like, sink, vanity and bathroom taps etc. shower mixer

    ReplyDelete
  128. togel sidney, data sidney, merupakan situs judi togel online terbaik dan terbesar no 3 di indonesia, yuk gabung segera di situs asiktogelku. minimal deposit 25.000 saja. data sdy

    ReplyDelete
  129. לא כל כך מסכים עם הכל כאן האמת.

    רעות מלכין עיצוב גבות

    ReplyDelete
  130. Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog.Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog.


    car opening service

    ReplyDelete
  131. I was exactly searching for. Thanks for such a post and please keep it up.
    Clear Water Management

    ReplyDelete
  132. If you will use the Re.rockspace.local login web domain, then the configuration will be very simple and easy for you, it hardly matters the model number and the update version. The users need to have Ap.setup access through the web browser that they will be using in their mobile or the computer device.

    ReplyDelete
  133. Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog.Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog.


    Houston Garage Door 4 Business

    ReplyDelete
  134. It's always exciting to read articles from other writers and practice something from their websites.
    local locksmith

    ReplyDelete
  135. Thanks for sharing this wonderful post with us. This is more helpful for explain how elder law lawyers thinks about families and their future.

    ReplyDelete
  136. If you have any problems regarding how to fix Orbi Won't Connect to WiFi issue, then don't worry; you can consult with our experienced experts. To get 24*7 instant help, you can just dial our toll-free helpline numbers at USA/CA: +1-855-869-7373 and UK/London: +44-800-041-8324.

    ReplyDelete
  137. Call our printer offline tech experts to fix issues of Brother Printer Can’t Connect To WiFi. If you want to know how to fix it, then don't hesitate to get in touch with us in the USA/CA: +1-888-966-6097 and UK/London: +44-808-169-7737. We are available 24*7 hours for you.

    ReplyDelete
  138. Hi there, I just wanted to say thanks for this informative post, can you please allow me to post it on my blog?

    etobicokecarlocksmith.com

    ReplyDelete
  139. แจกโปรโมชั่นอีกแล้วมาสนุกกับการเดิมพันของเว็บเกมสล็อตออนไลน์กับ pg slot ทางเข้าเล่น ตอนนี้ทางเรามีโปรโมชั่นมาแจกให้กับผู้ชื่นชอบการเดิมพันทุกท่าน กับเว็บเกมสล็อตออนไลน์ยอดฮิตที่มีความนิยมเป็นอย่างมากในตอนนี้ มีเกมส์หลายสไตล์ให้ลงเล่น เพียงท่านทำการสมัครสมาชิกกับเราก็จะได้รับโปรโมชั่นรับโบนัส 100% ทันที และสมาชิกเก่า ยังมีโปรโมชั่นคืนยอดเสียรับโบนัส 10% อีกด้วย สมัครสมาชิกกันเลยตอนนี้

    ReplyDelete
  140. IWEBCODE is the Best Website Design and Development Company in Mohali that provides all possible solutions to your Digital problems. For more details visit here: - https://iwebcode.design/

    ReplyDelete
  141. I have been reading your posts regularly. I need to say that you are doing a fantastic job. Please keep up the great work.


    stratford management scam

    ReplyDelete
  142. Nice blog. Get your and insights into the Latest Phones and Technologies. A place, where you can rely on true and authentic reviews before your phone purchase.

    ReplyDelete
  143. Thanks for some other informative site. The place else may I am getting that type of information written in such a perfect approach? สมัครยูฟ่าเบท I’ve a challenge that I am simply now running on, and I have been on the look out for such information.

    ReplyDelete
  144. This is a wonderful article, Given so much info in it, These type of articles keeps the user's interest in the website. Lock Installation

    ReplyDelete
  145. Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog.Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog.


    transponder key programming

    ReplyDelete
  146. I think this is an informative post and it is very useful and knowledgeable. therefore, I would like to thank you for the efforts you have made in writing this article. ยูฟ่า168

    ReplyDelete
  147. Are you having trouble trying to login to dlink router account? Worry no more. Here are straightforward guides to help you login successfully into your dlink router account. In addition, you do not have to bother about how much time it will take. In a few minutes, you will be done.
    Dlinkap.local
    Dlinkrouter.local

    ReplyDelete
  148. Have you been wondering what the wifi password for your Asus router is? It is very easy. A default password comes with Asus wifi router for easy login and setup. You will find the correct Asus router password default here so that you can begin with your login or setup.
    Login to Asus Router
    Router.asus.com
    Reset Asus Router

    ReplyDelete
  149. If you are finding it hard to login into your Orbi wifi router, there is a solution here for you. We have answered your question under the blog “why is my orbilogin.com not working”. Here you will find the answers to why you are experiencing login difficulties and the solutions.

    Orbi Login
    Orbi Router Login

    ReplyDelete
  150. Thanks for sharing this wonderful post with us. This is more helpful for explain crypto tax Australia.

    ReplyDelete
  151. Do you have any issues regarding how to fix Brother Printer Error 50? Then no need to worry; you can just dial our toll-free numbers at USA/CA: 1-888-966-6097 for better customer service. We are here always ready to help you. Get in touch with us for more information.

    ReplyDelete
  152. Thanks for sharing this wonderful post with us. This is more helpful for find the best top it company in the Bhutan Country. It also gives us well knowledge about business and websites related information.

    ReplyDelete
  153. Thanks for sharing this wonderful post with us. This is more helpful for find the best open source erp system in the Bhutan Country.

    ReplyDelete