Monday, April 12, 2010

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

[ part 1, part 2, part 3 ]

Creating your own error codes

As I stated in part 1, one of the principles behind the <system_error> facility is user-extensibility. This means that you can use the mechanism just described to define your own error codes.

In this section, I'll outline what you need to do. As a basis for a worked example, I will assume you're writing an HTTP library and need errors that correspond to the HTTP response codes.

Step 1: define the error values

You first need to define the set of error values. If you're using C++0x, you can use an enum class, similar to std::errc:

enum class http_error
{
continue_request = 100,
switching_protocols = 101,
ok = 200,
...
gateway_timeout = 504,
version_not_supported = 505
};

The errors are assigned values according to the HTTP response codes. The importance of this will become obvious when it comes to using the error codes. Whatever values you choose, errors should have non-zero values. As you may recall, the <system_error> facility uses a convention where zero means success.

You can use regular (that is, C++03-compatible) enums by dropping the class keyword:

enum http_error
{
...
};

Note: C++0x's enum class differs from enum in that the former encloses enumerator names in the class scope. To access an enumerator you must prefix the class name, as in http_error::ok. You can approximate this behaviour by wrapping the plain enum in a namespace:

namespace http_error
{
enum http_error_t
{
...
};
}

For the remainder of this example I will assume the use of enum class. Applying the namespace-wrapping approach is left as an exercise for the reader.

Step 2: define an error_category class

An error_code object consists of both an error value and a category. The error category determines whether a value of 100 means http_error::continue_request, std::errc::network_down (ENETDOWN on Linux), or something else entirely.

To create a new category, you must derive a class from error_category:

class http_category_impl
: public std::error_category
{
public:
virtual const char* name() const;
virtual std::string message(int ev) const;
};

For the moment, this class will implement only error_category's pure virtual functions.

Step 3: give the category a human-readable name

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

const char* http_category_impl::name() const
{
return "http";
}

This name does not need to be universally unique, as it is really only used when writing an error code to a std::ostream. However, it would certainly be desirable to make it unique within a given program.

Step 4: convert error codes to strings

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

std::string http_category_impl::message(int ev) const
{
switch (ev)
{
case http_error::continue_request:
return "Continue";
case http_error::switching_protocols:
return "Switching protocols";
case http_error::ok:
return "OK";
...
case http_error::gateway_timeout:
return "Gateway time-out";
case http_error::version_not_supported:
return "HTTP version not supported";
default:
return "Unknown HTTP error";
}
}

When you call the error_code::message() member function, the error_code in turn calls the above virtual function to obtain the error message.

It's important to remember that these error messages must stand alone; they may be written (to a log file, say) at a point in the program when no additional context is available. If you are wrapping an existing API that uses error messages with "inserts", you'll have to create your own messages. For example, if an HTTP API uses the message string "HTTP version %d.%d not supported", the equivalent stand-alone message would be "HTTP version not supported".

The <system_error> facility provides no assistance when it comes to localisation of these messages. It is likely that the messages emitted by your standard library's error categories will be based on the current locale. If localisation is a requirement in your program, I recommend using the same approach. (Some history: The LWG was aware of the need for localisation, but there was no design before the group that satisfactorily reconciled localisation with user-extensibility. Rather than engage in some design-by-committee, the LWG opted to say nothing in the standard about localisation of the error messages.)

Step 5: uniquely identify the category

The identity of an error_category-derived object is determined by its address. This means that when you write:

const std::error_category& cat1 = ...;
const std::error_category& cat2 = ...;
if (cat1 == cat2)
...

the if condition is evaluated as if you had written:

if (&cat1 == &cat2)
...

Following the example set by the standard library, you should provide a function to return a reference to a category object:

const std::error_category& http_category();


This function must always return a reference to the same object. One way to do that is to define a global object in a source file and return a reference to that:

http_category_impl http_category_instance;

const std::error_category& http_category()
{
return http_category_instance;
}

However, using a global does introduce issues to do with order of initialisation across modules. An alternative approach is to use a locally scoped static variable:

const std::error_category& http_category()
{
static http_category_impl instance;
return instance;
}

In this case, the category object is initialised on first use. C++0x also guarantees that the initialisation is thread-safe. (C++03 makes no such guarantee.)

History: In the early design stages, we considered using an integer or string to identify an error_code's category. The main issue with that approach was ensuring uniqueness in conjunction with user extensibility. If a category was identified by integer or string, what was to stop collisions between two unrelated libraries? Using object identity leverages the linker in preventing different categories from having the same identity. Furthermore, storing a pointer to a base class allows us to make error_codes polymorphic while keeping them as copyable value types.

Step 6: construct an error_code from the enum

As I showed in part 3, the <system_error> implementation requires a function called make_error_code() to associate an error value with a category. For the HTTP errors, you would write this function as follows:

std::error_code make_error_code(http_error e)
{
return std::error_code(
static_cast<int>(e),
http_category());
}

For completeness, you should also provide the equivalent function for construction of an error_condition:

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

Since the <system_error> implementation finds these functions using argument-dependent lookup, you should put them in the same namespace as the http_error type.

Step 7: register for implicit conversion to error_code

For the http_error enumerators to be usable as error_code constants, enable the conversion constructor using the is_error_code_enum type trait:

namespace std
{
template <>
struct is_error_code_enum<http_error>
: public true_type {};
}

Step 8 (optional): assign default error conditions

Some of the errors you define may have a similar meaning to the standard's errc error conditions. For example, the HTTP response code 403 Forbidden means basically the same thing as std::errc::permission_denied.

The error_category::default_error_condition() virtual function lets you define an error_condition that is equivalent to a given error code. (See part 2 for the definition of equivalence.) For the HTTP errors, you can write:

class http_category_impl
: std::error_category
{
public:
...
virtual std::error_condition
default_error_condition(int ev) const;
};
...
std::error_condition
http_category_impl::default_error_condition(
int ev) const
{
switch (ev)
{
case http_error::forbidden:
return std::errc::permission_denied;
default:
return std::error_condition(ev, *this);
}
}

If you choose not to override this virtual function, an error_code's default error_condition is one with the same error value and category. This is the behaviour of the default: case shown above.

Using the error codes

You can now use the http_error enumerators as error_code constants, both when setting an error:

void server_side_http_handler(
...,
std::error_code& ec)
{
...
ec = http_error::ok;
}

and when testing for one:

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

Since the error values are based on the HTTP response codes, we can also set an error_code directly from the response:

std::string load_resource(
const std::string& url,
std::error_code& ec)
{
// send request ...

// receive response ...

int response_code;
parse_response(..., &response_code);
ec.assign(response_code, http_category());

// ...
}

You can also use this technique when wrapping the errors produced by an existing library.

Finally, if you defined an equivalence relationship in step 8, you can write:

std::error_code ec;
data = load_resource("http://some/url", ec);
if (ec == std::errc::permission_denied)
...

without needing to know the exact source of the error condition. As explained in part 2, the original error code (e.g. http_error::forbidden) is retained so that no information is lost.

In the next part, I'll show how to create and use custom error_conditions.

108 comments:

  1. Just so you know, I find this articles very interesting cause I'm in the process of designing an error class for my personal library. I wasn't sure what to you use (an enum ?) and now I can see other options. Thanks.

    ReplyDelete
  2. Overriding the virtual function message(int ev) creates an compiler error, because enum class can not implicitly converted into int

    ReplyDelete
  3. Thanks for the good article.
    The one it useful for me because I have the similar issue with my project in ideals. So now I can try to fix it on my own.

    ReplyDelete
  4. Thank y, and I'm agree with the guys, its very important to understand how it works.
    security-online.net

    ReplyDelete
  5. As far as I understand you must not use the ec (error_code variable) alone in conditional context as it expects 0 as success, while in this particular case 200 (ok) is a success while 0 means nothing at all. Am I right?

    Why wasn't this addressed in the design? Was there no way to push the bool evaluation to external function that could be (with ADL) provided by user? Especially that HTTP codes are not the only case. Windows COM HRESULT codes for example include many success values.

    ReplyDelete
  6. "Researching" on this "framework" I came across error_condition description on the C++ Reference site (http://www.cplusplus.com/reference/system_error/error_category/). It provides an example of custom category that deals with HTTP status codes.

    Referring to my previous comment handling of many possible and non-zero error codes meaning success state is done by providing error_condition for the success state. Still doing if(ec) will not work with ec being 200, but doing if(ec == success) will do.

    ReplyDelete
  7. Online casino is the best solution to money issues the best online casino with us come in and win.

    ReplyDelete
  8. I thought protecting the website from the hackers is a hectic task. This post makes it easy for the developers and business people to protect the website. Keep sharing posts like this…
    Hire Magento developer India
    Hire a Programmer
    Hire a Coder
    Hire wordpress developer India
    Hire Dedicated Programmers

    ReplyDelete
  9. Great Article. Thank you for sharing! Really an awesome post for every one.

    IEEE Final Year projects Project Centers in Chennai are consistently sought after. Final Year Students Projects take a shot at them to improve their aptitudes, while specialists like the enjoyment in interfering with innovation. For experts, it's an alternate ball game through and through. Smaller than expected IEEE Final Year project centers ground for all fragments of CSE & IT engineers hoping to assemble. Final Year Project Domains for IT It gives you tips and rules that is progressively critical to consider while choosing any final year project point.

    Spring Framework has already made serious inroads as an integrated technology stack for building user-facing applications. Spring Framework Corporate TRaining the authors explore the idea of using Java in Big Data platforms.
    Specifically, Spring Framework provides various tasks are geared around preparing data for further analysis and visualization. Spring Training in Chennai

    ReplyDelete
  10. Nice Information. Thanks for sharing this Post. Are you looking for web design and logo design for your company or business please contact Subraa your freelance website designer and logo designer in Singapore. Structure your business website and get your logo FREE.

    Click the below links know more the offers:

    Logo Design
    Logo Design Singapore
    Logo Designer Singapore
    Web Designer Singapore
    Digital Marketing Agency in Singapore
    Flyer Design Singapore
    Name Card Design Singapore

    ReplyDelete
  11. nice way of sharing the information but here also the main other topic which is best ever for anyone who wants to read about the Moi. All the service is about the online Service information provider.

    ReplyDelete
  12. Nice Information. Thanks for sharing this Post.
    Click the below links know more the information:
    it development outsourcing
    eastern europe outsourcing
    test automation outsourcing

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

    ReplyDelete
  14. Incredible tips and straightforward blogpost indeed. This will be exceptionally helpful for me when I get an opportunity to begin my blog. But when it comes down to voting, most will not come down to wild cards.

    If you ever need a recommendation on website design, you can check us out at the web design and development company in Singapore.

    And if you also happen to be looking for swimming lessons, you can check us out at friendly dolphin swim school, we provide swimming lessons for all. And this skincare expert to help you provide you with the best skin after swimming.

    ReplyDelete
  15. Welcome to the Join Pak Navy if someone interested to apply for pak navy then they can visit this site as we almost cover everything related to this topic.

    ReplyDelete
  16. Your Blog is incredible with unique content. Please visit Sindh High Court to get latest Daily Cause List, Memorandum Civil, Criminal, Court Writ, Latest Jobs and Electronic Case Management System in Sindh High Court.

    ReplyDelete
  17. Hello, I'm happy to see some great articles on your site. Would you like to come to my site later? My site also has posts, comments and communities similar to yours. Please visit and take a look. ufa168

    ReplyDelete
  18. hey i am so happy for this error and system solution . thanks you for sharing this article .

    ReplyDelete
  19. The only address for those who want quality service is here. They provide services on the way of transportation with technological tools.
    İstanbul adana ambarı
    İstanbul antalya ambarı
    İstanbul hatay ambarı

    ReplyDelete
  20. Wow! It is a completely different topic. Great choice of Topic! You can apply for a Turkey visa online. You can get your Turkey Visa in just 1 hour by selecting the express processing type. It only takes 5 minutes to apply for an electronic visa Turkey. Apply Online.

    ReplyDelete
  21. Learn about Prophets by profeter bok i norge. This book has Prophets Knowledge and about their personalities and acknowledgements.

    ReplyDelete
  22. I am browsing this website daily and get good facts from here all the time. Aw, this was a really nice post. Kenya evisa processing time, Kenyans can apply for their eVisa in about 15 minutes by filling and submitting the visa application form.

    ReplyDelete
  23. Keep sharing such a great article! Are you stuck with your assignment? GoAssignmentHelp is one of the best Nursing Assignment Help service providers that provide best engineering assignment help to those students who face these issues and write Solidworks Assignment Help and score good grades.

    ReplyDelete
  24. First of all, thank you for your post. 바카라사이트 Your posts are neatly organized with the information I want, so there are plenty of resources to reference. I bookmark this site and will find your posts frequently in the future. Thanks again ^^

    ReplyDelete
  25. It has fully emerged to crown Singapore's southern shores and undoubtedly placed her on the global map of residential landmarks. I still scored the more points than I ever have in a season for GS. I think you would be hard pressed to find somebody with the same consistency I have had over the years so I am happy with that. 메이저토토사이트

    ReplyDelete
  26. Wow, that's what I was looking for, what stuff! Present here on this website, thanks to the admin of this website.. Turkish visa is an electronic travel authorization which is a 100% online Turkish e visa process, which takes hardly 3-5 minutes to fill out an online application.

    ReplyDelete
  27. Gayet güzel bir yazı. Bu arada https://apkdiot.com/nulls-brawl-apk-elmas-hileli-mod-indir-son-surum/ sürümünü indirmenizi öneriyorum.

    ReplyDelete
  28. It is very interesting information and it is very attractive. I really admire this blog... I agree, the article is very interesting and I like it very much. India eVisa policy map, you can read all guidelines related to India evisa Policy via India evisa website online.

    ReplyDelete
  29. Thank you.. Get the azerbaijan electronic visa through online e visa application to travel to Azerbaijan. Just follow 3 steps, fill application, upload document and make online payment for Azerbaijan e visa.

    ReplyDelete
  30. The content you shared with us is great. Thanks for sharing it. You can check out urgent e visa India fees by clicking the link we just provided. Thanks for adding value to the post.

    ReplyDelete
  31. It is a good site,Thank you.. How long is a medical visa valid for? Indian Medical Visa is valid for 60 days from the date of arrival in India. 3 entries are allowed for Indian Medical Visa.

    ReplyDelete
  32. Do you need Australia Assignment Help? We have the best online assignment writing service for this. We have a team of assignment helpers who will do any kind of academics assignment.

    ReplyDelete
  33. This is new knowledge for me, I am excited about it. Thanks.... evisa to India, you can apply for an online e visa to India visa through Indian visa website.

    ReplyDelete
  34. bu güzel bilgi için teşekkür ederim artık bazı şeyleri yapacağız

    ReplyDelete
  35. Simply desire to say your article is as amazing. The clearness on your post is simply spectacular and that i could assume you are a professional on this subject.
    바카라사이트

    ReplyDelete
  36. Pretty good post. I just stumbled upon your blog and wanted to say that I have really enjoyed reading your blog posts. 스포츠토토

    ReplyDelete
  37. This site is a great stepping stone for any player that is just getting started with online gambling. 경마

    ReplyDelete
  38. I like your all post. You have done really good work. Thank you for the information you provide, it helped me a lot 릴게임

    ReplyDelete
  39. The information mentioned inside the post are a number of the very best accessible 토토

    ReplyDelete
  40. Hii everyone, nice information for a new blogger…it is really helpful. emergency Indian visa for US citizen, US citizen can be apply for India visa online easily. Within 5 to 10 minutes you can fill your form and in 1 to 3 working days you can get your visa.

    ReplyDelete
  41. When it comes to protecting your home or business, an alarm system is one of the most important investments you can make. Alarm systems deter burglars and intruders, and can even alert the authorities in the event of a break-in. alarm systems

    ReplyDelete
  42. If you're looking for the perfect place to host your next conference, look no further than our conference facilities. Conference Facilities Yorkshire

    ReplyDelete
  43. We can provide all the assistance you need to set up your business in Mauritius in accordance with the Business Registration Act so that you can focus on your prime goals and let us handle the rest. Mauritius Business Registration

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

    ReplyDelete
  45. Venuepro is made up of 14 comprehensive modules that deliver all aspects of event and venue management. Venuepro is constantly under further development by consulting with industry experts and global venue and space owners. venue management systems uk

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

    ReplyDelete
  47. www.smmfk.com | Türkiye'nin En Kaliteli ve En Hesaplı SMM Paneli! 🚀

    ⭐️ TÜM SOSYAL MEDYA PLATFORMLARINA HİZMET VAR ⭐️

    ⭐️ PİYASANIN EN UCUZ SERVİSLERİ⭐️

    🚀 Telafili Servisler Jet Hızında 🚀

    Fiyatlarımız Türkiye'nin En Ucuzu !

    ℹ Daha Fazla Ucuz Servis İçin Web Sitemizi Ziyaret Edebilirsiniz.
    🌏 https://smmfk.com/

    ©️ Instagram Hesabımız: www.instagram.com/smmfkcom

    ☎️ 7/24 Canlı Destek
    🖥 7/24 Çalışan Tam Otomatik SMM Panel
    💳 PayTR 3D Secure Güvenli Ödeme Sistemi

    ReplyDelete
  48. about straight on the labor: this is my first mechanical watch,fałszywych zegarków I have done some homework in the love watch family and other forums before,Replica Louboutin Red Bottom and firmly into the idea of labor, although there was also the idea of receiving a TAG Heuer or other entry mechanical watch to play with, but then I think I actually only need a practical and can replica cartier watches always carry on the line, since sooner or later on the labor, why not take a little detour, a step in place (this is only for people who want to (This is only for those who want to go to Lau, and I don't mean to belittle other brands ......)

    ReplyDelete
  49. Şirketiniz evriminin neresinde olursa olsun, geleceği planlamak çok önemlidir. Planlama, olumsuz durumlara hazırlanmaya ve şirketin gelişimi için eylemleri tasarlamaya yardımcı olur. Bu yazıda, organizasyonel planlama için en faydalı araçlardan biri olan SWOT Analizini tartışacağız.

    ReplyDelete
  50. siber güvenlik, kripto para, kripto para incelemeleri, uygulama incelemeleri, uygulama karşılaştırmaları, ürün, teknoloji, internet ve daha fazlası. lorentlabs

    ReplyDelete
  51. Udaipur, formerly the capital of the Mewar Kingdom, is a city in the western Indian state of Rajasthan. Founded by Maharana Udai Singh II in 1559, it’s set around a series of artificial lakes and is known for its lavish royal residences. City Palace, overlooking Lake Pichola, is a monumental complex of 11 palaces, courtyards and gardens, famed for its intricate peacock mosaics.
    Golden Triangle Tour with Udaipur (8 Days 7 Nights) FLAT 30% OFF | Golden Triangle Tour Packages With Udaipur | Golden Triangle Tour With Udaipur | 7 Days Delhi Agra Jaipur Udaipur Tour | Golden Triangle With Udaipur Tour

    ReplyDelete
  52. This particular papers fabulous, and My spouse and i enjoy each of the perform that you have placed into this.
    This particular papers fabulous,nice information...Good blog.
    Replica Gucci Handbags Sale
    Replica Gucci Bags Store
    Yeezy boost 350V2 Shoes
    replica Louis Vuitton Bags
    replica Louis Vuitton Handbags

    ReplyDelete
  53. Sosyal Medya Nedir
    Sosyal medya, kullanıcıların anında bilgi üretmesine ve halkla paylaşmasına izin veren herhangi bir dijital teknolojidir. Sosyal medya, çok çeşitli web siteleri ve uygulamalar içerir. Twitter gibi bazıları, bağlantıları ve kısa yazılı mesajları paylaşmaya odaklanmıştır. Instagram gibi diğerleri, fotoğraf ve video paylaşımını kolaylaştırmak için tasarlanmıştır.

    Sosyal medyayı diğerlerinden ayıran şey, aynı anda geniş ve bir şekilde sınırsız olmasıdır. Birçok sosyal medya işletmesi, şiddeti veya çıplaklığı tasvir eden fotoğrafları kaldırmak gibi belirli kısıtlamalar getirirken, insanların yayınlayabilecekleri şeyler konusunda dergiler, radyo istasyonları ve televizyon gibi geleneksel kitle iletişim biçimlerinden çok daha az kısıtlama vardır.

    İnternet bağlantısı olan herkes sosyal medya profili oluşturabilir. Bu profili, beğendikleri herhangi bir içeriği yayınlamak için kullanabilirler ve paylaştıklarını, sayfalarını veya hesaplarını görüntüleyen herkes görebilir. Anında fotoğraf, görüntü ve etkinlik yayınlama kapasitesi, insanların yaşama ve iş yapma şeklini değiştirdi.



    Sosyal Medya Nasıl Çalışır?
    Birçok sosyal medya uygulaması türü olduğu için, bu araçların rolü de değişir. Öte yandan, çoğu sosyal medya platformu, genellikle bir kullanıcı adı ve bir e-posta hesabı girerek bir kullanıcının hesap oluşturmasıyla başlar.



    Resim Kaynağı: Arama Motoru Günlüğü

    Kullanıcılar bir profil oluşturduktan sonra içerik üretebilir ve paylaşabilir. Örneğin, yeni bir hesabı olan bir Instagrammer, bir fotoğrafı tıklayıp hesabına bir resim yazısı ile yükleyebilir. Ayrıca sosyal medya kullanıcıları, içeriklerini takip etmek veya tepki göstermek istedikleri diğer kullanıcıları tanımlayabilir ve profillerine içerik sağlayabilir. Örneğin, bir kullanıcı başka bir kişiyi "takip edebilir", onu "arkadaş" olarak ekleyebilir veya sosyal medyanın biçimine göre başka bir kullanıcının sayfasına "kaydolabilir".

    Sosyal medya, sık sık, kullanıcıların içerikte gezinmesine olanak tanıyan "beslemeler" kullanır. Sosyal medya işletmeleri, bir kişinin profil verilerine bağlı olarak görüntülenen bilgileri ve görüntülenme sırasını tahmin etmek için algoritmalar kullanır. İçeriklerinin reklamını yapmak için ödeme yapan "takip eden" kişilerden ve şirketlerden gelen içerikler, feed'e dahil edilecektir.



    Sosyal Medya Türleri
    Sosyal medyanın çeşitli biçimleri vardır ve çeşitli hizmetler sunarlar; Aşağıda örneklerle birlikte birkaç sosyal medya türü listelenmiştir.



    Görüntü Kaynağı: Bugün Tıp Haberleri

    Sosyal Ağ
    Bu tür sosyal medya, fikirleri, görüşleri ve içeriği diğer kullanıcılarla paylaşmakla ilgilenir. Facebook ve Twitter sosyal ağların en iyi örnekleridir. LinkedIn başka bir sosyal ağdır. Ancak, daha sofistike ve profesyonel.

    Medya Ağları
    Kullanıcılar, resimler, videolar ve diğer içerikler gibi medya varlıklarını birbirleriyle paylaşmak için bu tür sosyal medyayı kullanır. Medya ağlarının en iyi örnekleri YouTube , Pinterest , TikTok, Twitch , Flickr , Vimeo ve Instagram'dır . İnsanlar bu sitelere medya gönderir ve diğer kullanıcılar tercihlerine göre beğenebilir, beğenmeyebilir ve yorum yapabilir.

    Ağları İncele
    İnceleme ağları, ürün ve hizmetlerin değerlendirilmesine yardımcı olur. Yelp , TripAdvisor ve Amazon'u içerir .

    Tartışma Ağları
    Bu platformlar, dünya çapındaki insanların bir dizi sorunu tartışmasına olanak tanır. Tartışma ağlarının en iyi örneklerinden bazıları Reddit ve Quora'dır .

    ReplyDelete
  54. Apple Kimliği, iCloud’da oturum açmak ve iTunes Store ve App Store‘dan öğe satın almak için kullandığınız bir hesaptır. iPhone veya iPad’inizde bir uygulama, kitap veya şarkı satın aldıysanız, Apple Kimliğinin ne olduğunu biliyorsunuzdur. Apple kimliğinizi kullanmak isterken bazen “Bu Apple kimliği henüz App Store ile kullanılmadı” gibi hatalar ile karşılaşabilirsiniz. Kullanıcıların kafasını karıştıran bu sorunun sebebi birçok şeyden kaynaklanıyor olabilir.
    bu apple kimliği henüz app store ile kullanılmadı

    ReplyDelete
  55. Saçınız bazı nedenlerden dolayı kırılmaya, yıpranmaya ve cansız bir hal alması kaçınılmazdır. Yediğiniz yemekler, yaşadığınız çevre bile saçınıza etki etmektedir. Herhangi bir bakım ürünü kullanmazsanız bu durumlar karşınıza gelebilir. Bu olumsuzluktan korunmak için çeşitli yollar mevcuttur. Yazımızdan keratin nedir, keratin bakımı fiyatı ve keratin botox hakkında tüm detaylara ulaşabilirsiniz.

    ReplyDelete
  56. Sparkling chess academy is one of the best chess coaching academies in Delhi- NCR, under the supervision of brilliant teachers. The quality of training which is given here makes it one of the favorite spots for chess coaching in Delhi .

    ReplyDelete
  57. canlı borsa nice blog site. I will visit again. Good luck.

    ReplyDelete
  58. nice blog site. I will visit again. Good luck.

    ReplyDelete
  59. nice blog site. I will visit again. Good luck.

    ReplyDelete
  60. nice blog site. I will visit again. Good luck.

    ReplyDelete
  61. nice blog site. I will visit again. Good luck.

    ReplyDelete
  62. nice blog site. I will visit again. Good luck.

    ReplyDelete
  63. nice blog site. I will visit again. Good luck.

    ReplyDelete
  64. nice blog site. I will visit again. Good luck.

    ReplyDelete
  65. nice blog site. I will visit again. Good luck.

    ReplyDelete