Is there any way to programmatically differentiate between what caused an IOException? For example Java will throw an IOException, if there was an error during writing. How can I tell, if it's something like access violation, if the Disk is out of free space, if someone disconnected the the network drive, or other things?
I can't really parse the Message since, there does not seem to be any standardized message format, Sun (or Oracle now I guess) doesn't seem to have any sort of standardized format.
(I need to use Java to fix a very broken system at work.)
Unfortunately Java has no equivalent of .NET's System.Runtime.InteropServices.Marshal.GetHRForException(). You tell what kind of I/O error it was only if the exception is an instance of a subclass, e.g. FileNotFoundException.
Getting a hold of the exception's exact class will give you one of a handful of possible subclasses of IOException, and these are quite standardized. You can either test classes with instanceof or (a brutish approach) compare strings returned from getClass().getName().
There are some workarounds for the other stuff; you can do a File.canWrite() on a file you're about to open for writing (well, your program should have done that anyway, if the name and/or directory can vary), and if there's a chance you ran out of file space, you could try writing a small file to a known good location and seeing if that explodes on you. Not very elegant, I know: Java is not really known as a systems programming language.
On the other hand, very often knowing a detailed cause for an exception doesn't help much: With or without the knowledge, your user may simply not be able to get the program to do what's needed.
Related
I am a newbie with designing stuff though I have some experience as a developer. My question is related to the statement -
"It is always a good practice to design the exception hierarchy at the start of the project"
After much of reading and researching the definition of a checked and unchecked exception is well clear.
However, I still wonder what is the best practices in designing the exception hierarchy for an application. Is the below approach right?
Create your own application specific top level exceptions
MyAppRuntimeException
MyAppCheckedException
Subclass MyAppCheckedException with all your business exceptions where you want the caller to take a specific exception. For example
TryWithADifferentInputException - This is not the right input, correct it
TryAlternateServiceException - This service is not available, but you can choose another service that will do the job
Similarly subclass your runtime exception which spiral up and are captured only by something like the spring exception resolver and display appropriate message on front end.
Another thing that bugs me is how to come up with most of the exception scenarios at the start of the project. What should be the strategy to do so.
Hello hailMurphy and welcome to SO!
IMO, it is not necessary to design an entire exception hierarchy for every app. Rather, you should only introduce new exceptions if none of the existing stock ones adequately address the error you're encountering.
Your TryWithADifferentInputException for instance could probably easily be replaced with an IllegalArgumentException or possibly IllegalStateException. I find that 99% of the time, I'm well able to do with the existing ones.
As for knowing which exceptions to expect before you actually start writing code: The complex parts of your program, such as class structure, algorithms, protocols, etc. should be thought out and documented before you actually fire up your IDE and get hands-on. UML is a common way to do this. During that process, as you're pen-and-papering your algorithm or protocol, try looking at border cases (what happens when this value becomes zero? What if this argument is null? Will my algorithm still work? Good! Will it break? Exception!) and playing devil's advocate (what if the network connection breaks down halfway through my protocol? Can I recover from this, or does it leave me in an unrecoverable state?) you should be able to see exception scenarios.
If you do find yourself in need for creating custom exceptions, derive them directly from whichever ancestor seems most fit - Error, IllegalStateException, RuntimeException, IOException, etc. Don't create your own complete hierarchy unless there is a scenario where you need to only catch all of your own exceptions and none of the stock ones. Honestly, though, I can't see a scenario where that might be useful.
On a more general note, exceptions should be a "last resort" to deal with errors that can't be otherwise recovered from, and not as a form of control flow. If you're expecting something to happen naturally as part of your application (such as bad user input), you should generally not deal with it through exceptions. If you have an algorithm that breaks unrecoverably in a lot of cases, it can be an indication that you haven't found the right one yet.
Well, I am not going to answer all of your questions, but just the parts that I know based in my experience.
The idea of create the exceptions at the begining just have sense if we have the design of the app really clear. I mean, we have to know the flows of the app and what could happen. If we dont know the design more than 80% probably we will change many things, including exceptions hierachy, many times.
Furthermore, If our app is designed correctly and at the coding stage a new exception appears, should be easy the addition in the exceptions tree.
Well I hope be clear for you.
Bye
Let's say you are writing a generic doSomething method where you check a string argument for validity:
public void doSomething(String argument) {
if(!checkArgument(argument)) {
// Argument is not valid
throw new IllegalArgumentException("Argument " + argument + " is not valid");
}
...
Is throwing an Exception whose message can contain potentially arbitrary text safe? Or can it expose the program to log forging or some other security issues?
Is there any best practice to handle such cases?
It really depends on what you are going to do with the exception after it is thrown.
In general, I'd say this is probably a bad idea. As a rule of thumb you should never "use" unsanitized arguments. Here are a few attack scenarios this might open you up to.
This is for a webpage and you are displaying this error to the user. In this case the attacker could execute a XSS attack, among other things.
This error will be printed to a log. Here it may seem safe, but the attacker still has some (all be it limited) access to your file system. They could use this mechanism to store code for future use, or possibly damage the log (or other aspects of the file system). This is especially true if argument is written byte for byte to a file.
This error will be stored in a database. Here with enough schema information the attacker may be able to alter, or destroy the entirety of the database.
On it's own this might not be enough for an attacker to steal any information, but combined with other bugs this could be used to gain control of the machine. You could do some basic sanitization though and avoid most of these issues.
As suggested by #assylias perform length checking.
Ensure all characters in argument are alphanumeric (or whatever you expect things in arg to be).
If alphanumeric is to restrictive, pass through any whitelist that doesn't include html/javascript/sql syntax characters (e.g. '<','>',';') Usually these characters do not need to be present for debugging anyways.
Generally safe, but you should decide whether to allow exceptions to be visible to end users if the code is executing on a system under your control (e.g. a web server). Showing internal information in error messages in exceptions is a form of Information Leakage as it can reveal information about how your system is built and an attacker can probe for vulnerabilities by forcing exceptions. This may not apply if it is a desktop application, as this is effectively under user control anyway, but extra caution is needed to anything web or internet based.
However, you could add logic to your custom error handler page to only show the details of exceptions that derive from MyUserExceptionClass which you make it your policy to only use when the end user can rectify the error. In this case you'll probably only want to show the message itself and not output any stack trace or other details, in which case your exception message should contain details of the argument name if it is relevant to the end user.
To address the points in diedthreetimes's answer, these should not be of concern to the exception throwing class or the exception class itself. The class that uses the unsanitised data should sanitise it for the context it is output.
e.g.
If output in an HTML page, HTML encode the exception message at point of output, not at point of exception throwing.
The error logging class should sanitise the unsanitised text into the correct format for the log. If there is a character limit or if it is a CSV formatted file then this class should ensure that any commas and quote characters in the message are formatted properly at this point.
If written to the database, it is up to the Data Access Layer to correctly write the information into the database using parameterised queries.
I broadly agree with SilverlightFox's answer. Worry about injection vulnerabilities at the point they occur (and make sure they cannot occur).
However, confidentiality issues are a real problem with exceptions. Elsewhere (unless we have globals) we are dealing with interactions over a single layer-interface. Bring in exceptions and we have non-local issues.
For example:
SSNs are the canonical example of data that needs tight controls. Some low-level parsing library may throw an exception with details of the string. That may be caught and shoved into a log. Neither generic parsing code nor logging code know about SSNs but they've ended up introducing an SSN vulnerability.
Web sites that put exception messages into web pages (sometimes in comments - that doesn't help!) disclose information about the web site implementation that may be helpful to an adversary. Web sites should not do this, but they do. Therefore, you need to think carefully about any code that throws exception and could end up in a web app some day.
Exceptions propagated between processes, or machines, or operating system to pross, or whatever, may carry confidential information.
Where there is mobile code, confidential information may be slip down to less privileged code. File paths are the obvious candidate here.
It's also worth noting that adding mutable data to exceptions is a bad idea, as it needs a deep copy to be safe. It's a shame that 1.4 made Throwable itself "usefully" mutable.
You can log the argument and include a substring in exception.
For your concern on security it depends on access control model of your application and infrastructure.
If server is not accessible to all, then logging is a good idea at least you can have a look at what argument caused exception.
If security is a higher concern, I would suggest storing exception details in a database table along with parameter for analysis.
If you want to go crazy you can encrypt your database column.
In any case I think one would like to have a look at what argument caused exception.
Cheers !!
Seeing a checked expection in API is not rare, one of the most well known examples is IOException in Closeable.close(). And often dealing with this exception really annoys me. Even more annoying example was in one of our projects. It consists from several components and each component declares specific checked exception. The problem (in my opinion) is that at design time it was not exactly known what certain exceptions would be. Thus, for instance, component Configurator declared ConfiguratorExeption. When I asked why not just use unchecked exceptions, I was told that we want our app to be robust and not to blow in runtime. But it seams to be a weak argument because:
Most of those exceptions effectively make app unusable. Yes, it doesn't blow up, but it cannot make anything exepting flooding log with messages.
Those exceptions are not specific and virtually mean that 'something bad happened'. How client is supposed to recover?
In fact all recovering consists from logging exception and then swallowing it. This is performed in large try-catch statement.
I think, that this is a recurring pattern. But still checked exceptions are widely used in APIs. What is the reason for this? Are there certain types of APIs that are more appropriate for checked exceptions?
There have been a lot of controversy around this issue.
Take a look at this classic article about that subject http://www.mindview.net/Etc/Discussions/CheckedExceptions
I personally tend to favor the use of Runtime exceptions myself and have started to consider the use of checked exceptions a bad idea in your API.
In fact some very popular Java API's have started to do the same, for instance, Hibernate dropped its use of checked exceptions for Runtime from version 3, the Spring Framework also favor the use of Runtime over checked exceptions.
One of the problems with large libraries is that they do not document all the exceptions that may be thrown, so your code may bomb at any time if an undocumented RuntimeException just happens to be thrown from deep down code you do not "own".
By explicitly declaring all those, at least the developer using said library have the compiler help dealing with them correctly.
There is nothing like doing forensic analysis at 3 in the morning to discover that some situation triggered such an undeclared exception.
Checked Exceptions should only be thrown for things that are 1) Exceptional they are an exception to the rule of success, most poor exception throwing is the terrible habit of defensive coding and 2) Actionable by the client. If something happens that the client of the API can't possibly affect in any way make it a RuntimeException.
There's different views on the matter, but I tend to view things as follows:
a checked exception represents an event which one could reasonably expect to occur under some predictable, exceptional circumstances that are still "within the normal operating conditions of a program/typical caller", and which can typically be dealt with not too far up the call stack;
an unchecked exception represents a condition that we "wouldn't really expect to occur" within the normal running environment of a program, and which can be dealt with fairly high up the call stack (or indeed possibly cause us to shut down the application in the case of a simpler app);
en error represents a condition which, if it occurs, we would generally expect to result in us shutting down the application.
For example, it's quite within the realms of a typical environment that under some exceptional-- but fairly predictable-- conditions, closing a file could cause an I/O error (flushing a buffer to a file on closing when the disk is full). So the decision to let Closable throw a checked IOException is probably reasonable.
On the other hand, there are some examples within the standard Java APIs where the decision is less defensible. I would say that the XML APIs are typically overfussy when it comes to checked exceptions (why is not finding an XML parser something you really expect to happen and deal with in a typical application...?), as is the reflection API (you generally really expect class definitions to be found and not to be able to plough on regardless if they're not...). But many decisions are arguable.
In general, I would agree that exceptions of the "configuration exception" type should probably be unchecked.
Remember if you are calling a method which declares a checked exception but you "really really don't expect it to be thrown and really wouldn't know what to do if it were thrown", then you can programmatically "shrug your shoulders" and re-cast it to a RuntimeException or Error...
You can, in fact, use Exception tunneling so that a generic exception (such as your ConfiguratorException) can give more detail about what went wrong (such as a FileNotFound).
In general I would caution against this however, as this is likely to be a leaky abstraction (no one should care whether your configurator is trying to pull its data from the filesystem, database, across a network or whatever)
If you are using checked exceptions then at least you'll know where and why your abstractions are leaky. IMHO, this is a good thing.
At the company where I am right now, there are a lot of places in the code where an OurCompanyRuntimeException is thrown (where OurCompany is the actual name of the company). As far as I can tell, this exception is described as "A runtime exception thrown by code that we wrote here at this company."
I'm somewhat new to Java, but I thought exception types were supposed to reflect what went wrong, not whose code threw the exception. For example, IllegalArgumentException means someone passed an illegal argument to something. You wouldn't have a SunIllegalArgumentException if an illegal argument was passed in code written by Sun, and then a IBMIllegalArgumentException -- that would be silly and pointless, right? And if you want to know where the exception was thrown, you look at the stack trace. I understand wanting to extend RuntimeException (so that you don't have as many try/catches or "throws"es all over) but why not make subclasses that explain what happened, as opposed to what company's code it happened in?
Has anyone ever used the OurCompanyRuntimeException idea before, or have an idea of why they might have done it this way?
Sounds like the usual bespoke code nonsense that you find in in-house code bases to me. I suspect if you ask about there'll have been some decree that the OurCompanyRuntimeException was used based on some misguided logic by a senior guy that nobody dared question and has long since moved on - the story of the monkeys, bananas and hose-pipes springs to mind.
I agree with you, the name of the exception should be indicative of the error that has occurred.
Helps when reading stack traces, that's for sure. I.e. when scanning through a lot of lines of 'caused by's', it helps to see that it occurred in something thrown by you, not something internal to, say, a container.
Also lets you perform custom actions as part of the throwable - e.g. write to a special log somewhere, etc.
Yes I encountered that, too, but it didn't make sense to me either. My guess was, that the companies wrote this exceptions very early after the adoption of Java without getting the correct idea of how exception throwing and handling really works (like Nick already said... by the senior programmer nobody dared to question).
If the company feels the need to create its own exception class (e.g. for company specific logging porpuses) this exception should never be thrown directly (making it abstract). I would derive concrete Problem describing Exceptions instead or just follow the Spring Framework's idea for Exception handling/throw.
This is a bad concept. Exceptions should be specific for a use case.
Okay, if the company does produce a lot of faulty code/products, they may use that type of exception as advertisement ;)
Your company might be adding code to an already existing project, like an open source code base, and could have just added very little code to it. So in order to trace errors that happen by the company's developers, they thought that they would have their own exception class to distinguish the errors that were there before, from the ones caused by the extension. This way, they can focus only on the ones that are caused by company's developers, and perhaps ask the original source code maintainers to fix the other ones.
With time, when you people have developed a sufficiently large code base through in-house development, you may add more exceptions and remove the CompanynameRuntimeException altogother. Also, they might get more at ease with the level of expertise of the developers, to allow them to treat all errors like one, and not to view the ones caused by company developers more suspiciously.
It would make very good sense to have this as a baseclass for specific exceptions. You thrown a specific exception and catch the base class.
Also it may allow to carry a cause (the REAL exception) plus additional information around. That can be very handy for creating diagnostic output for logging.
Seems pretty silly, logging output or a stack trace will show you who the offending class is, so that explanation doesn't wash. Also seems dangerous, as if people are encouraged to throw the OurCompanyRuntimeException they're throwing RuntimeExceptions, which don't force the caller to handle them and can take down your application.
I agree with you that exceptions should reflect the reason behind them. I've seen a custom exception as the root of a hierarchy, although it probably ought to be abstract, so that you need to create a specific extension to use one, and it definitely shouldn't be a RuntimeException.
It wouldn't be a bad idea to have a generic company wide exception class like you describe that more specific exception cases inherit from. One answer already mentioned the ability specifically catch internal code exceptions and ignore / pass through the ones from core java or third party library code. The key point here is that more specific exceptions should inherit from this one. Throwing a generic company-named exception would be rarely required, and almost never recommended.
I know Googling I can find an appropriate answer, but I prefer listening to your personal (and maybe technical) opinions.
What is the main reason of the difference between Java and C# in throwing exceptions?
In Java the signature of a method that throws an exception has to use the "throws" keyword, while in C# you don't know in compilation time if an exception could be thrown.
In the article The Trouble with Checked Exceptions and in Anders Hejlsberg's (designer of the C# language) own voice, there are three main reasons for C# not supporting checked exceptions as they are found and verified in Java:
Neutral on Checked Exceptions
“C# is basically silent on the checked
exceptions issue. Once a better
solution is known—and trust me we
continue to think about it—we can go
back and actually put something in
place.”
Versioning with Checked Exceptions
“Adding a new exception to a throws
clause in a new version breaks client
code. It's like adding a method to an
interface. After you publish an
interface, it is for all practical
purposes immutable, …”
“It is funny how people think that the
important thing about exceptions is
handling them. That is not the
important thing about exceptions. In a
well-written application there's a
ratio of ten to one, in my opinion, of
try finally to try catch. Or in C#,
using statements, which are
like try finally.”
Scalability of Checked Exceptions
“In the small, checked exceptions are
very enticing…The trouble
begins when you start building big
systems where you're talking to four
or five different subsystems. Each
subsystem throws four to ten
exceptions. Now, each time you walk up
the ladder of aggregation, you have
this exponential hierarchy below you
of exceptions you have to deal with.
You end up having to declare 40
exceptions that you might throw.…
It just balloons out of control.”
In his article, “Why doesn't C# have exception specifications?”, Anson Horton (Visual C# Program Manager) also lists the following reasons (see the article for details on each point):
Versioning
Productivity and code quality
Impracticality of having class author differentiate between
checked and unchecked exceptions
Difficulty of determining the correct exceptions for interfaces.
It is interesting to note that C# does, nonetheless, support documentation of exceptions thrown by a given method via the <exception> tag and the compiler even takes the trouble to verify that the referenced exception type does indeed exist. There is, however, no check made at the call sites or usage of the method.
You may also want to look into the Exception Hunter, which is a commerical tool by Red Gate Software, that uses static analysis to determine and report exceptions thrown by a method and which may potentially go uncaught:
Exception Hunter is a new analysis
tool that finds and reports the set of
possible exceptions your functions
might throw – before you even ship.
With it, you can locate unhandled
exceptions easily and quickly, down to
the line of code that is throwing the
exceptions. Once you have the results,
you can decide which exceptions need
to be handled (with some exception
handling code) before you release your
application into the wild.
Finally, Bruce Eckel, author of Thinking in Java, has an article called, “Does Java need Checked Exceptions?”, that may be worth reading up as well because the question of why checked exceptions are not there in C# usually takes root in comparisons to Java.
Because the response to checked exceptions is almost always:
try {
// exception throwing code
} catch(Exception e) {
// either
log.error("Error fooing bar",e);
// OR
throw new RuntimeException(e);
}
If you actually know that there is something you can do if a particular exception is thrown, then you can catch it and then handle it, but otherwise it's just incantations to appease the compiler.
The basic design philosophy of C# is that actually catching exceptions is rarely useful, whereas cleaning up resources in exceptional situations is quite important. I think it's fair to say that using (the IDisposable pattern) is their answer to checked exceptions. See [1] for more.
http://www.artima.com/intv/handcuffs.html
By the time .NET was designed, Java had checked exceptions for quite some time and this feature was viewed by Java developers at best as controversial controversial. Thus .NET designers chose not to include it in C# language.
Fundamentally, whether an exception should be handled or not is a property of the caller, rather than of the function.
For example, in some programs there is no value in handling an IOException (consider ad hoc command-line utilities to perform data crunching; they're never going to be used by a "user", they're specialist tools used by specialist people). In some programs, there is value in handling an IOException at a point "near" to the call (perhaps if you get a FNFE for your config file you'll drop back to some defaults, or look in another location, or something of that nature). In other programs, you want it to bubble up a long way before it's handled (for example you might want it to abort until it reaches the UI, at which point it should alert the user that something has gone wrong.
Each of these cases is dependent on the application, and not the library. And yet, with checked exceptions, it is the library that makes the decision. The Java IO library makes the decision that it will use checked exceptions (which strongly encourage handling that's local to the call) when in some programs a better strategy may be non-local handling, or no handling at all.
This shows the real flaw with checked exceptions in practice, and it's far more fundamental than the superficial (although also important) flaw that too many people will write stupid exception handlers just to make the compiler shut up. The problem I describe is an issue even when experienced, conscientious developers are writing the program.
Interestingly, the guys at Microsoft Research have added checked exceptions to Spec#, their superset of C#.
Anders himself answers that question in this episode of the Software engineering radio podcast
I went from Java to C# because of a job change. At first, I was a little concerned about the difference, but in practice, it hasn't made a difference.
Maybe, it's because I come from C++, which has the exception declaration, but it's not commonly used. I write every single line of code as if it could throw -- always use using around Disposable and think about cleanup I should do in finally.
In retrospect the propagation of the throws declaration in Java didn't really get me anything.
I would like a way to say that a function definitely never throws -- I think that would be more useful.
Additionally to the responses that were written already, not having checked exceptions helps you in many situations a lot. Checked exceptions make generics harder to implement and if you have read the closure proposals you will notice that every single closure proposal has to work around checked exceptions in a rather ugly way.
I sometimes miss checked exceptions in C#/.NET.
I suppose besides Java no other notable platform has them. Maybe the .NET guys just went with the flow...