What is the closest you can get to a try-catch block in php4?
I'm in the middle of a callback during an xmlrpc request and it's required to return a specifically structured array no matter what.
I have to error check all accesses to external resources, resulting in a deep stack of nested if-else blocks, ugly.
Late answer, I realise, sorry. I hope this is still relevant for you:
First, I'm echoing the comments your got in response to your post. PHP5 is the way to go.
However:
I'm in the middle of a callback during
an xmlrpc request and it's required to
return a specifically structured array
no matter what.
If you can vouch for that the program cannot possibly continue without getting a structured array back, and you absolutely have to work with PHP4, then an exit() or die() with detailed error information will get you much the same effect as a fatal exception would.
That's far removed from being graceful, of course. If you want something catchable, then return values and if-checking the result are your best bet, unfortunately. There are some standard ways of passing back specific error objects, but it's still the same thing - return the error object, if-check whether the result was an error object, react.
Still, take a look at PEAR's error object.
Related
In my experience, every language which supports exceptions has a hierarchy of exception types. This allows a single catch clause to match a group of related exceptions by catching their common parent. For example, part of Python's hierarchy:
FloatingPointError < ArithmeticError < Exception < BaseException
Go, on the other hand, famously does not support exceptions and also has "no type hierarchy". Some people think exceptions should be added to Go - would it be possible to do this without adding a type hierarchy?
Are there other languages which have exceptions but no type hierarchy? Do they group related exceptions in some other way?
SuperTalk has effectively no data types, but has exceptions. Basically you throw an error code and check that. That's also how many early macOS application frameworks worked, even in C++.
So just as an object can be approximated by using a simple data structure with a type selector, exceptions can be made to work.
on doFoo
throw "myError"
end doFoo
on startUp
try
doFoo
catch tError
if tError = "myError" then
-- do something about it
else
throw tError
end if
end try
end startUp
Instead of "myError", you can throw any string or number, so you could use a formatted string, like "copyFileError,/path/to/source/file.txt,/path/to/dest/file.txt" (of course with proper escaping of dangerous characters like "," in this case) and then just compare the first item in this list to tell whether it's the error you want to handle.
If you're just going with error numbers without any additional payload, you can segment the number space to get error "classes" e.g. "fatal errors are negative, recoverable ones positive" or "1-100 are file system errors" or whatever (see HTTP status code for an example of using error code ranges to define error classes).
I'd rather post this as a comment, but the sentiment was too long to get across within the limitations of a comment. I am aware that this is primarily opinion based, and I apologize for that.
Go does not support exceptions because it does not need to. Exceptions are a crutch that developers have been lured into becoming dependent on because they don't want to handle errors properly. In Go, it is idiomatic to handle every error, on the spot, every time. If you do this, your programs run better, and you are aware of exactly when/where errors happen and you can fix them. Using catch in other languages ends up being more difficult to debug as you are not always aware of exactly where the error originally happened. By wrapping your code in try catch blocks, you essentially mask the bugs in your code. try and catch are also terribly inefficient because all of the optimizations in the binary grind to a halt as the program has to figure out what unexpectedly happened. Using errors properly in Go circumvents this because you capture errors and handle them, thereby "expecting" them as an eventuality and handling them properly.
It's easy to crash at runtime with unwrap:
fn main() {
c().unwrap();
}
fn c() -> Option<i64> {
None
}
Result:
Compiling playground v0.0.1 (file:///playground)
Running `target/debug/playground`
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', ../src/libcore/option.rs:325
note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: Process didn't exit successfully: `target/debug/playground` (exit code: 101)
Is unwrap only designed for quick tests and proofs-of-concept?
I can not affirm "My program will not crash here, so I can use unwrap" if I really want to avoid panic! at runtime, and I think avoiding panic! is what we want in a production application.
In other words, can I say my program is reliable if I use unwrap? Or must I avoid unwrap even if the case seems simple?
I read this answer:
It is best used when you are positively sure that you don't have an error.
But I don't think I can be "positively sure".
I don't think this is an opinion question, but a question about Rust core and programming.
While the whole “error handling”-topic is very complicated and often opinion based, this question can actually be answered here, because Rust has rather narrow philosophy. That is:
panic! for programming errors (“bugs”)
proper error propagation and handling with Result<T, E> and Option<T> for expected and recoverable errors
One can think of unwrap() as converting between those two kinds of errors (it is converting a recoverable error into a panic!()). When you write unwrap() in your program, you are saying:
At this point, a None/Err(_) value is a programming error and the program is unable to recover from it.
For example, say you are working with a HashMap and want to insert a value which you may want to mutate later:
age_map.insert("peter", 21);
// ...
if /* some condition */ {
*age_map.get_mut("peter").unwrap() += 1;
}
Here we use the unwrap(), because we can be sure that the key holds a value. It would be a programming error if it didn't and even more important: it's not really recoverable. What would you do when at that point there is no value with the key "peter"? Try inserting it again ... ?
But as you may know, there is a beautiful entry API for the maps in Rust's standard library. With that API you can avoid all those unwrap()s. And this applies to pretty much all situations: you can very often restructure your code to avoid the unwrap()! Only in a very few situation there is no way around it. But then it's OK to use it, if you want to signal: at this point, it would be a programming bug.
There has been a recent, fairly popular blog post on the topic of “error handling” whose conclusion is similar to Rust's philosophy. It's rather long but worth reading: “The Error Model”. Here is my try on summarizing the article in relation to this question:
deliberately distinguish between programming bugs and recoverable errors
use a “fail fast” approach for programming bugs
In summary: use unwrap() when you are sure that the recoverable error that you get is in fact unrecoverable at that point. Bonus points for explaining “why?” in a comment above the affected line ;-)
In other words, can I say my program is reliable if I use unwrap? Or must I avoid unwrap even if the case seems simple?
I think using unwrap judiciously is something you have to learn to handle, it can't just be avoided.
My rhetorical question barrage would be:
Can I say my program is reliable if I use indexing on vectors, arrays or slices?
Can I say my program is reliable if I use integer division?
Can I say my program is reliable if I add numbers?
(1) is like unwrap, indexing panics if you make a contract violation and try to index out of bounds. This would be a bug in the program, but it doesn't catch as much attention as a call to unwrap.
(2) is like unwrap, integer division panics if the divisor is zero.
(3) is unlike unwrap, addition does not check for overflow in release builds, so it may silently result in wraparound and logical errors.
Of course, there are strategies for handling all of these without leaving panicky cases in the code, but many programs simply use for example bounds checking as it is.
There are two questions folded into one here:
is the use of panic! acceptable in production
is the use of unwrap acceptable in production
panic! is a tool that is used, in Rust, to signal irrecoverable situations/violated assumptions. It can be used to either crash a program that cannot possibly continue in the face of this failure (for example, OOM situation) or to work around the compiler knowing it cannot be executed (at the moment).
unwrap is a convenience, that is best avoided in production. The problem about unwrap is that it does not state which assumption was violated, it is better instead to use expect("") which is functionally equivalent but will also give a clue as to what went wrong (without opening the source code).
unwrap() is not necessarily dangerous. Just like with unreachable!() there are cases where you can be sure some condition will not be triggered.
Functions returning Option or Result are sometimes just suited to a wider range of conditions, but due to how your program is structured those cases might never occur.
For example: when you create an iterator from a Vector you buid yourself, you know its exact length and can be sure how long invoking next() on it returns a Some<T> (and you can safely unwrap() it).
unwrap is great for prototyping, but not safe for production. Once you are done with your initial design you go back and replace unwrap() with Result<Value, ErrorType>.
I am calling a ASYNC method in an MVC4 application. This method has to call a dozen or so other methods, which are nested. My issue is that if any of these nested methods break, it passes the error to the parent method. Since they are all nested, it just keeps passing up the chain returning to the HTTP context the generic error message.
Since I have so many nested methods, I have no clue how to find more information on the error. Even a simple line that broke would be extremely helpful.
Right now I am resorting to breaking every line to see which ran last before it stop responding. This Method alone, with it's nested methods, are over 2000 lines of code. As you can tell, this is a very un-effective way at debugging.
Any help at a better way of finding out where a ASYNC method actually broke, when in nested methods, would be extremely helpful. I really want to avoid doing a Try/Catch on every method I have.
-- Edit --
This has been answered. I put my solution below and will mark it as answered in two days, per StackOverflow restrictions.
Apparently if I put a Try/Catch on the first call inside my Action Method it at least gives me the line in the stack trace. Once noting this, I added ELMAH and inspected my error log when throwing a generic exception. It appears that the line gets passed back to ELMAH also.
While this is not nearly as nice as normal exception breaking in visual studio, it allows me to easily put a breakpoint on that exact line to see what is happening.
Unfortunately, asynchronous "stack traces" do not work very well out of the box.
You can do your own tracing using a technique I describe in this blog post. Or you could try installing my async diagnostics package which adds the asynchronous "stack trace" to the exception's Data property (note: not logged by default in ELMAH). However, this package is not yet production-ready, so I recommend uninstalling before deploying.
I'm kind of torn between these two error-handling models:
Create a boolean Error and a string ErrorMessage property for your object. Catch all exceptions internally in the object's methods and pass the messages along using conditional logic from the caller, ie:
Dim o As New MyObject
o.SomeMethod()
If Not o.Error Then
'Do stuff'
Else
Dim msg As String = o.ErrorMessage
'do something with message'
End If
Throw exceptions in your object and handle them on the outside with Try Catch logic:
Dim o As New MyObject
Try
o.SomeMethod()
'Do stuff'
Catch ex As Exception
Dim msg As String = ex.ErrorMessage
'do something with message'
End Try
To me, it seems like the same amount of code either way, except that you have property code for the Error and ErrorMessage properties. However, you also can tell when an error occurs without having to check for exceptions. Which pattern should I go with?
I have decided to go with throwing exceptions instead of using error/return codes. I just recently looked really hard into this.
The #1 reason to throw exceptions is there is a possibility you can forget to check the error code. If you don't check it, then you will continue working while the error exists. With exceptions though, if you forget to handle them, then the exception will raise to the top and stop all processing. It is better for this to happen than to continue after unknown errors have occurred.
For more info check out the Exception chapter in Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, Second Edition by Addison-Wesley.
Joel Spolsky actually prefers error/return codes over exceptions but a lot of people disagree with him. Joel's post in favor of return codes can be found here. Check out this blog post and all of the comments with some good discussion regarding this subject.
Prefer #2. For details, see this excerpt on Exception Throwing from the development of Microsoft's excellent Framework Design Guidelines, as Dennis mentioned. Note especially the section on Exceptions and Performance.
Short version:
Do not return error codes.
Do report execution failures by throwing exceptions.
Do not use exceptions for normal flow of control.
I highly recommend reading the book for a full discussion, complete with commentary from a number of the Microsoft luminaries.
Exceptions should be used when something exceptional has happened.
e.g. you are passed a null (nothing) object when you expect one.
Uncle Bob recommends Exceptions over Error codes in his book Clean code.
He says
The problem with these [error codes] approaches is that they clutter the caller. The caller must check for errors immediately after the call. Unfortunately it's easy to forget. For this reason it is better to throw an exception when you encounter an error. The calling code is cleaner. Its logic is not obscured by error handling.
The biggest issue I have with the first one is that it's passive, easily overlooked and not very standardized. How will a programmer know to check that property? Or which properties / methods can possible set an error? Or which property / method access caused the error to be set?
For example. In your first sample code if o.Error is True, it's unclear whether the initialization of the object or the call to SomeMethod caused the flag to be set.
The exception model is an unignorable way of telling your users that an error occurred. It cannot be avoided without explicit code to handle the situation.
They are both accepted forms of error handling, however the preferred choice for .NET languages is to use exceptions.
There are a few problems with using return codes (either numeric or boolean), the two biggest being:
Easily overlooked/ignored by programmers.
Can't be used in all situations. What happens if your constructor fails? It's not possible for you to return a value explicitly from a constructor.
For these reasons alone, you should use exceptions. Exceptions provide a clean, standardized way to indicate and any failure no matter where it arises.
You will also end up with less code overall as you should only catch exceptions when and where you can safely and appropriately handle that exception.
I recommend using both.
Why?
"Use the right tool for the job"
The "problem" with return codes is that people often forget to handle them. However, exceptions don't solve this problem! People still don't handle exceptions (they don't realise a certain exception needs to be handled, they assume somebody up the stack will handle it, or they use a catch() and squash all errors).
While an unhandled return code might mean the code is in an unstable state, an unhandled exception often guarantees that the program will crash. Is this better?
While a return code is easily identifiable when writing code, it is often impossible (or just tediously time-consuming) to determine what exceptions might be thrown by a method you are calling. This typically results in a lot of very poor exception handling.
Exceptions are supposed to be used for "errors". Therein lies the difficulty. If a file is not found when you try to open it, is that an "error", or an "expected situation"? Only the caller knows. Using exceptions everywhere essentially elevates every piece of status information into an error.
Ultimately, error handling is something a programmer has to work at. This problem exists in both return codes and exceptions.
Thus, I use return codes for passing status information (including "warnings"), and exceptions for "serious errors". (and yes, sometimes it's hard to judge which category something falls under)
Example case from .net:
Int32.Parse throws exceptions (even though none of its exceptions are errors - it is up to the caller to verify the results and decide for themselves if the result is valid). And it's simply a pain (and a performance hit) to have to enclose every call to it in a try/catch. And if you forget to use a try/catch, a simple blank text entry field can crash your program.
Thus, Int32.TryParse() was born. This does the same thing, but returns an error code instead of an exception, so that you can simply ignore errors (accepting a default value of 0 for any illegal inputs). In many real life situations this is much cleaner, faster, easier and safer to use than Int32.Parse().
"TryParse" uses a naming convention to make it clear to the caller that errors might occur, that should be correctly handled. Another approach (to force programmers to handle errors better) is to make the return code into an out or ref parameter, so that the caller is explicitly made aware of the need to handle returned errors.
What’s the best practice when returning something from a routine? Should I return a status bit always or just on failure? For example:
Return(0, “Failed because….”) on failure,
Return(1, success_value, second_success_value) on success.
Or
Return(0, “Failed because….”) on failure,
Return( success_value, second_success_value) on success.
I usually program in Perl, but I guess the question stands for whatever language I might try to program in. Thanks!
The answer is very language dependent. You should follow the idiom for the language you are using. The idiom for Perl, which you mentioned, is to return zero(0) for success and other values for failure. If you need to return multiple values, as in your example, one of them could always be the success/failure code.
If you're using a language that supports exceptions (eg. Java, C#, C++) then you should indicate exceptional conditions (eg. failures) using an exception. If the routine completes normally (ie. no exceptions) then it can be assumed to have succeeded and any returned values can be used safely.
In languages that support them, you should throw descriptive exceptions.
Where applicable, you should throw exceptions of the correct type (eg, ArgumentNullException or InvalidOperationException in .Net)
hey Akers, I've asked myself a similar question in the past...
Some of these answers might help you
Is it bad practice to return Exceptions from your methods
The basic conclusion I came to is to only return something, anything, if the caller requires it.
So, for the most part, I found its better to just make my method Void, and have it throw a meaningful exception if anything goes wrong. If everything goes ok, then I, as the caller, don't really care