Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DM-9846: Improve handling of error messages #4

Merged
merged 4 commits into from Mar 22, 2017
Merged

Conversation

r-owen
Copy link
Contributor

@r-owen r-owen commented Mar 16, 2017

No description provided.

src/base.cc Outdated
// Construct ErrorHandler once, the first time this function is called.
// This is done to initialize `errorMsgStream` and register `reportError` as the AST error handler.
// See https://isocpp.org/wiki/faq/ctors#static-init-order
static ErrorHandler * errHandler = new ErrorHandler();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@r-owen r-owen Mar 17, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps I should change the link to https://isocpp.org/wiki/faq/ctors#static-init-order-on-first-use (which is the solution, and comes right before the discussion about why to use new.

Also, it may not be safe just rely on a link, as it may go stale. @jonathansick do we have a way to archive a useful page so we're sure we always have access to it? I'd hate to copy all that information to this note.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you need to copy all that information. The static initialization order issue is fairly well known (e.g., there's an item devoted to it in Effective C++), so a brief mention should be all the justification you need. The static de-initialization issue is not one I was familiar with, but it's exactly the same principle and so can probably be explained in one line.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@r-owen We don't have a formal system for that, but it's an interesting concept. Probably combining ls.st with an auto-archive service that fails over if the original link 404s. I'll put that in my idea bucket. Something probably exists off-the-shelf for this. In the meantime, webarchive.org can save us if the link goes stale.

Copy link
Member

@kfindeisen kfindeisen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No major problems, just some style nitpicks.

Longer term desires:
- Support AST regions
- Add support for building with cmake.
- Add doc strings to python wrapped objects.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to remove the "longer-term" bit as well?

Copy link
Contributor Author

@r-owen r-owen Mar 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. The current code will probably suffice for LSST and it's not clear to me which, if any, additional AST features we will want to add. Much as I would like python doc strings I suspect it is not practical unless we come up with an automated way to add them.

ErrorHandler() {
astSetPutErr(reportError);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is astshim bound by RFC-209? I'm not clear on its relationship to the Stack.

Copy link
Contributor Author

@r-owen r-owen Mar 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not bound but I have been doing that for most classes. It seems fussy for such a tiny class, but I'll add it.

src/base.cc Outdated
astSetPutErr(reportError);
}

std::string getErrMsg() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can getErrMsg() be made static?

src/base.cc Outdated
std::string getErrMsg() {
std::string errMsg = errorMsgStream.str();
errorMsgStream.clear();
if (errMsg.empty()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should clear() be called even if errMsg is empty?

Copy link
Contributor Author

@r-owen r-owen Mar 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe so. clear clears state flags, such as the error bit, so it is probably always best to call that. To empty the buffer requires calling str("") and I think I will do that only if a string was read. I added a test to test_object.py that makes sure the buffer is properly cleared.

@timj
Copy link
Member

timj commented Mar 21, 2017

Does this change make the AST error code itself available to the code that is catching the exception? It seems a bit lossy to end up with a RuntimeError that can not be used to work out what really went wrong without looking at the text of the error message.

@kfindeisen
Copy link
Member

That would be a nice feature, but I think it would require a custom exception. Perhaps as a separate ticket?

@timj
Copy link
Member

timj commented Mar 21, 2017

Something that's pretty easy in Python but I don't know how to do it in C++ so I'll leave the decision on that to the experts. I think it would be something that we should definitely have in the future though.

@r-owen r-owen force-pushed the tickets/DM-9846 branch 4 times, most recently from 384f04f to 228e0b7 Compare March 22, 2017 12:15
@r-owen
Copy link
Contributor Author

r-owen commented Mar 22, 2017

@timj Including the error code as a value in the exception would be a lot more work and I consider it out of scope for this ticket. We could easily print the AST status as part of the error message but I'm reluctant to do so without a demonstrated need; so far I have found the error messages perfectly clear by themselves.

Using the new AST function `astSetPutErr` write AST error messages
to an ostringstream and have `assertOK` use the contents of that
stream as the error message when it raises an exception.
python/astshim/keyMap.cc was moved into a subdirectory,
but somehow the original was still present (though ignored).
test_object.py was trying to call methods that were no longer
publicly available. This passed because it was checking for
errors (just not the ones being raised).
Improve test_channel.py and test_normMap.py to test for a
more explicit exception when using assertRaises.
I checked the usage in other tests and concluded it was best
to leave them as is because in some cases it wasn't clear which
C++ exception would be mapped to the Python exception that was
raised, and in others it was unclear if AST or C++ code would
catch the problem, thus which Python exception would be raised.
...about comparing unsigned int to int
@timj
Copy link
Member

timj commented Mar 22, 2017

Ok. I just feel uncomfortable throwing a runtime error for every possible AST problem. In pyast we go the other extreme and have a special exception for every AST error: https://github.com/timj/starlink-pyast/blob/master/tools/make_exceptions.py but it's probably the case that there should be groups of related error types triggering ValueError vs TypeError etc. I don't want to derail this PR but please consider in the future how you are catching exceptions and whether more granularity would lead to cleaner code.

@r-owen r-owen merged commit f375f38 into master Mar 22, 2017
@kfindeisen
Copy link
Member

kfindeisen commented Mar 24, 2017

@timj, @r-owen: this may be a stupid question, but are AST's error codes documented anywhere (they don't seem to be in the AST Programmer's Guide)? Adding the error code to an exception is rather pointless if a program can't do anything with the information.

@timj
Copy link
Member

timj commented Mar 24, 2017

The source of truth is at https://github.com/Starlink/ast/blob/master/ast_err.msg

I concur that the API document does not actually say which error codes are relevant for which method. Things like AST__ATTIN are equivalent to Python ValueError. @dsberry do you want to comment on this?

Most of the error codes are fatal, so I guess that a program will not need to care about specifics in those cases and the error message is fine. Some of them are recoverable (such as AST__VSMAL). It would be nice if the error codes were grouped into related exceptions but we didn't try that in pyast.

@kfindeisen
Copy link
Member

"Which error codes are relevant" is actually ill-defined on a method by method basis, because all methods share the same error flag. My question was more along the lines of "If I find out the error code was 42, what does that actually tell me?"

@timj
Copy link
Member

timj commented Mar 24, 2017

I'm not sure I understand you. If you ask for an attribute from an AST object that does not exist AST will trigger AST__ATGER or AST__BADAT. In Python you'd expect that to throw an exception that inherits from KeyError so you can trap it. You don't ever write "42" in your code. In C you would check to see if the error code was set to AST__ATGER (defined in ast_err.h) and respond accordingly. If you always get RuntimeError you can't make any decisions in the code and must always punt to the user to interpret the error message.

@r-owen
Copy link
Contributor Author

r-owen commented Mar 24, 2017

astshim attempts to raise appropriate exceptions. The python wrapper needs a bit of work on that, but the C++ is probably OK.

@ktlim ktlim deleted the tickets/DM-9846 branch August 25, 2018 04:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants