Exception while reading journal entry's body

Jun 21, 2010 at 6:04 PM

In my code I am iterating through the messages in all PST folders an reading their properties (subjects, body, attachments dates etc). One of my test PSTs contains a journal entry message (of the type IPM.Activity). When I try to read the body of this message using get_body() throws "key not found" exception while trying to read PR_BODY tag. The PR_BODY does not exist for  journal entry mesages, but I don't think throwing an exception is a right solution. Returning an empty string  would be better

Coordinator
Jun 21, 2010 at 6:23 PM

Well, the problem is an empty body/string is different than a body not being there at all - so we can't just return an empty string. It's like if you were reading an integer property; we could just return 0 if the property doesn't exist, but 0 is also a perfectly valid value for an integer property.

In general, as a modern C++ library the SDK is built around using exceptions as the primary error handling mechanism.

Jun 21, 2010 at 9:00 PM

I agree about using exceptions as error handing mechanism, but in this particular case "key not found exception" coming from read_prop(0x1000) while executing get_body() is not easily understandable. Besides the user has to know that 0x1000 is PR_BODY and check for its existance everytime the body is needed in order to avoid an exception. In this case why bothder using get_body(). If one needs to know that body is a property 0x1000  read_prop() or open_prop_stream() can be used.

 if (props.prop_exists(0x1000)) {
   wstring body= msg.get_body();
 }

Coordinator
Jun 21, 2010 at 9:14 PM

Well, it's clear to me for the above reasons that when you call get_body and the item doesn't have a body property, an exception of some type must be thrown. However, I do think that key_not_found<prop_id> is a little esoteric - I might create a new exception type class prop_not_found : public key_not_found<prop_id> { ... }; just so the exception type is a little clearer.

The idea that a bool body_exists() method, or more generally a bool XXX_exists(); method is added everywhere we have a get_XXX() property in the PST layer is interesting though, as this will (as you point out) allow users to not have to know the property id of the XXX property if they are just trying to do the basics. I'll think more about it.

Jun 23, 2010 at 12:03 AM

I'm using the following (rather ugly) function to read properties:

template <typename R, typename T, typename D>
R prop_or(const T &obj, R (T::*pmf)() const, D default_value) {
    try {
        return (obj.*pmf)();
    } catch (key_not_found<prop_id> &) {
        return default_value;
    }
}

This can be called as follows:

prop_or(m, &message::get_subject, L"No subject")

Obviously, it would be better to rewrite this using boost::optional or something else that can represent a "null" value cleanly. But if this helps anybody as is, please feel free to use it!

Jun 26, 2010 at 3:29 PM

Here's a slightly cleaner variation of the idea:

    template <typename R, typename T>
    bool has_prop(const pstsdk::message &m, R (T::*pmf)() const) {
        try {
            (m.*pmf)();
            return true;
        } catch (key_not_found<prop_id> &) {
            return false;
        }
    }
Oct 19, 2010 at 10:35 PM

Since I am looking for a nice way to get most properties of a message and I am not a C++ star, can somebody tell me if the this last function is handy and how I use it? Can I pass a property address to it or something?

Coordinator
Oct 19, 2010 at 11:28 PM

If you want to get most properties off of a message, I recommend you unwrap the message object to the underlying property_bag, which has methods to tell you exactly what properties are present.

Oct 20, 2010 at 10:02 PM

ok, thanks for your answer, but is this last function of ekidd usefull and how do I use it? is it something like has_prop(m, 0x0037) ? would be usefull I think?