I am trying to call method that creates a file, however I am calling that method from the Action Performed which simply can not have throws IOException...
Here is the code:
/* ACTION PERFORMED**/
public void actionPerformed(ActionEvent evt){
Object source = evt.getSource();
if (source == add)
{
String mothername = " ";
String fathername = " ";
String motherphone = " ";
String fatherphone = " ";
Patient patient = new Patient(...));
printPatients(patient);
System.out.println("past printing patient");
writetoFile(patient); //giving an error
}
if (source == uadd)
{
Patient patient = new Patient(...));
printPatients(patient);
writetoFile(patient); //giving an error
}
}
//This is the method I am trying to call
public static void writetoFile(Patient p) throws IOException
{
RandomAccessFile inout = new RandomAccessFile("PatientsInfo.dat", "rw");
inout.seek(inout.length());
inout.writeUTF(p.getName());
inout.writeUTF(p.getAge());
inout.writeUTF(p.getGender());
inout.writeUTF(p.getSiblings());
inout.writeUTF(p.getID());
inout.writeUTF(p.getNationality());
inout.writeUTF(p.getCivilStatus());
inout.writeUTF(p.getProfession());
inout.writeUTF(p.getPhone1());
inout.writeUTF(p.getPhone2());
inout.writeUTF(p.getEmail());
inout.writeUTF(p.getMotherName());
inout.writeUTF(p.getFatherName());
inout.writeUTF(p.getMotherPhone());
inout.writeUTF(p.getFatherPhone());
inout.writeUTF(p.getMedication());
inout.writeUTF(p.getDoctorsName());
inout.writeUTF(p.getFrequency());
inout.writeUTF(p.getPrice());
System.out.println("names and sentinel value sent to file Countries.dat");
inout.close();
}
//The error is in the two blue lines, and the error it shows is:
Error: C:\Users\Pedro Quintas\Documents\Documents and Work
\Escola\Computer Science\Programs\Dossier\AddPatient.java:362:
unreported exception java.io.IOException; must be caught or
declared to be thrown
Please tell me what to change
The answer is in the error message :) You have to handle your exceptions. They aren't there just to blow things up when things go slightly askew -- they are there for you to figure out how you want to handle your errors when they happen. This means that you have to think about which portions of your program are going to handle error conditions, and which portions of your program are going to assume that errors don't happen.
You might want your actionPerformed() method to place an error dialog box on screen to alert the user that the 'save' button in fact threw away all their work. In that case, wrap all those calls to writeToFile() in try/catch blocks and handle appropriately.
You might want your writeToFile() to log a message to the log4j instance logging your application, or simply spit something to standard error or standard out when writing fails. In that case, undelcare throws IOException from your writeToFile(), wrap the contents of the method in a try/catch block and handle appropriately.
Handling errors is, at least in my experience, most of the code of most applications. It's a pity schools don't teach it better, but here's your opportunity to learn what design tradeoffs you have by trying both of my suggestions here and noticing the effects elsewhere in the program.
Related
I am writing some validation code and am not sure how to pass validation messages back to the calling code.
Exceptions come to mind, but I think that Exceptions should not be used in user input validation. As #Blowdart puts it:
Exceptions are not
control flow mechanisms. Users often get passwords wrong, it's not an
exceptional case. Exceptions should be a truly rare thing,
UserHasDiedAtKeyboard type situations.
From: https://stackoverflow.com/a/77175/125938. I'm extending that sentiment to all "incorrect" user input that a user might enter.
So the question is what to use instead of Exceptions. For certain situations, I could just use an IsValid… method that returns a bool for validity, but what if I want to pass an error message back with it? Should I create a custom "ValidationError" object, with a Message property? What makes sense and causes Least Astonishment (preferably a tried and tested pattern)?
If I were to do this in a truly object-oriented way, I'd adhere to the separation of concerns principle and compose a chain of classes that each deal with a separate step on the input - validation - output journey.
Let's say we are parsing a date from string as entered by the user.
My first class would encapsulate the raw value and attempt to parse the date (pseudo-code):
class TextualDate {
public TextualDate(string value) {
// just initialize with the provided value
}
public Option<Date> AsDate() {
// try parsing and either return the date or not
// the Option<Date> type is here to suggest that the conversion might not succeed
}
}
Next I'd have a validation class that instantiates the TextualDate class, invokes its AsDate() method and returns the validation result:
class ValidatedDate {
public ValidatedDate(TextualDate value) {
// initialize with the provided value
_textualDate = value;
}
private TextualDate _textualDate;
public ValidationResult Validated {
var maybeDate = _textualDate.AsDate();
// see whether we have a date or not
return new ValidationResult(...);
}
}
In our ValidationResult class, we might find some status property (OK, Failed), any error message either provided directly or as a key to then look-up in a message catalog etc.
This way, we can isolate concerns and only deal with the error messages on the UI layer while being able to use and reuse the validation logic independently.
I was faced with a similar dilemma in the past - I had to write a couple of services that takes data from a 3rd party, manipulating it in various ways, and send that data to other services for further processing.
All of these services might have failed because of wrong or incomplete data, but it was nor unexpected neither exceptional - and I refused to use exceptions for these cases.
I've done an extensive research, reading anything I could get my hands on in this subject in two days, and finally decided the following:
A method might need to return data and might not (sub in Visual Basic, void in Java/C#) - but in both cases, I wanted an indication for success/fail and a potential error message.
If your language of choice supports tuples, you could return a tuple from your methods:
public (bool Success, string ErrorMessage) DoSomething()
{
// implementation here
}
or
public (bool Success, someType Value, string ErrorMessage) DoSomething()
{
// implementation here
}
If not, you can do what I did (That was c#5 - so no value tuples) and create a result class:
public class Result
{
public static Result Success()
{
return new Result(true, null);
}
public static Result Fail(string errorMessage)
{
return new Result(false, errorMessage);
}
protected Result(bool success, string errorMessage)
{
Success = success;
ErrorMessage = errorMessage;
}
public bool Success {get; private set;}
public string ErrorMessage {get; private set;}
}
public class Result<T>
{
public static Result<T> Success(T value)
{
return new Result(true, null, value);
}
public new static Result<T> Fail(string errorMessage)
{
return new Result(false, errorMessage, default(T));
}
private Result<T>(bool success, string errorMessage, T value)
: base(success, errorMessage)
{
Value = value;
}
public T Value {get; private set;}
}
And use it like this:
public Result CouldBeVoid()
{
bool IsOk;
// implementation
return IsOk ?
Result.Success() :
Result.Fail("Something went wrong") ;
}
public Result<int> CouldBeInt()
{
bool IsOk;
// implementation
return IsOk ?
Result.Success(intValue) :
Result.Fail("Something went wrong") ;
}
var result = CouldBeVoid();
if(!result)
// do something with error message
var result = CouldBeInt()
if(result)
// do something with int value
else
// do something with error message
Users often get passwords wrong, it's not an exceptional case.
Yes and no. Whether to throw an exception or not depends on the question you're asking. And in the course of logging a user in, there are typically quite a number of questions being asked before you come to the conclusion whether the user can be logged in or not. The more you break down your code into specialised parts, the more it may make sense to raise exceptions in some of those parts.
Say you specify your login procedure the following way in an HTTP context:
Get the username* and password* from the request.
Fetch the user record* by its username from the database*.
Check whether the record's password* equals* the entered password.
If yes, start a session.
If any of the above steps do not successfully complete, output an appropriate error message.
Any of the items marked with an asterisk above may fail:
The request may not contain a username or password.
There may not be a user record for this username, or the database may be down.
For whatever reason, the record may not have a password and/or be corrupted. The stored password may, for whatever reason, use an unsupported hashing algorithm and hence can't be compared.
It should be rather obvious that in this process there are any number of cases that would be ideal to be implemented as an exception. The actual function which tests the password should probably not throw an exception in case the password is merely false; that should be a boolean return value. But it may still throw an exception for any other number of reasons. If you use exceptions properly, you'll end up with code that looks something like this (pseudo-pseudo code):
try {
username = request.get('username')
password = request.get('password')
user = db.get(username=username)
if (user.password.matches(password)) {
session.start()
} else {
print 'Nope, try again'
}
} catch (RequestDoesNotHaveThisDataException) {
logger.info('Invalid request')
response.status(400)
} catch (UserRecordNotFoundException) {
print 'Nope, try again'
} catch (UnsupportedHashingAlgorithmException, PasswordIsNullException) {
logger.error('Invalid password hash for user ' + user.id)
response.status(500)
print 'Sorry, please contact our support staff'
} catch (DatabaseDownException e) {
// mostly for illustration purposes,
// this exception should probably not even be caught here
logger.exception('SEND HALP!')
throw e
}
So, yes, this is a very simple process, but literally every step along the way has one or more exceptional cases. You ask the question "what is the username the user sent in the request?", and if there's no answer to this question because the user didn't sent any username, you have an exceptional case. Exceptions simplify control flow here a lot as opposed to trying to cover each of these cases with an if..else.
It is NOT an exception if the username is not valid or the password is not correct.
(From the answer you quote from.)
As you can see, we're testing whether the username is "valid" or not by trying to fetch its record from the database. If we have a function whose purpose is to fetch records of users from the database, and there is no such record, then an exception is an entirely valid response. If we defined that function to test whether such a record exists and null or false is a valid return value… fine. But in this case we didn't write it that way, and frankly, that results in simpler control flow I find.
Now, only the password validation itself does not use an exception, since the question asked there is "does this password match that password?", to which the answer can clearly be yes or no. Again, only if something exceptional like an unsupported hashing algorithm turns up can there be no answer to this question and an exception is entirely warranted.
Having said all this, you may notice that most of these cases, except the really fatal one with the database, does not outwardly result in an exception. The component here is expecting and handling certain cases that its sub-components regard as exceptional. This code here is asking the questions, and is prepared to handle Mu as an answer for some of them. Which is to say, a general rule that says "exceptions shouldn't be used in process X, Y or Z because it's not exceptional enough" is too dogmatic. It depends on the purpose of each individual piece of code whether an exception is warranted or not.
Having said all this, what you're asking about is some sort of form validation. The above code shows a case where two pieces of data may each be invalid, and it's using exceptions to in the end still result in a "yes" or "no" response. You can of course encapsulate that in an object like this:
val = new LoginFormValidator()
val.setDataFromRequest(request)
val.validate()
if (val.isValid) {
print 'Hurray'
} else {
print 'You have errors:'
for (error in val.errors) {
print error.fieldName + ': ' + error.reason
}
}
Whether this validator uses exceptions internally for any of this you do not need to care, but in the end it saves all of them as a "yes" or "no" result to its internal properties, from where you can take them either as an aggregate (val.isValid) or individually (for (error in val.errors)).
I have Processing 3 code that is exhibiting some odd behavior. I have a void exit() method defined that is being executed at random times without the user actually telling the code to exit. Here is the method:
void exit()
{
println("clearing buffer and closing file");
if (output != null) {
print("output is not null");
try {
output.close();
}
catch (IOException e) {
println("Error while closing the writer");
}
}
super.exit();
}
As you can see, the only thing that it does is attempt to close a buffered writer called output. Flushing this writer is not critical, so for now I am just removing it from my sketch. But long term, I am curious how this can be happening. Nowhere else in my code is the exit method explicitly called. IE, the code cannot decide to exit. It is only when the user closes the problem using the X.
Note: I cannot upload the entire code this method is attached too because it is too long. I think perhaps a better way to phrase my questions would be something like:
"Hi, I am a noob that doesn't know anything about the exit method. Is there anyway that this method could somehow get called without me explicitly calling it or hitting the exit button?"
Add this at the beginning of your exit() method.
new Exception().printStackTrace();
The resulting stacktrace should allow you to figure out what is calling your exit() method.
Or if you can't tweak the code, you can run the application using a debugger and set a breakpoint at the start of the exit() method.
To answer your question about whether it is possible, the answer depends on what you mean by "without me explicitly calling". There are various ways to call a method, some of which are quite obscure; e.g.
You can use reflection to get the Method object for the exit method from the declaring class, and then call invoke(...) on it.
You can call a Java method from native code via the JNI or JNA apis.
You can generate Java source code that contains an exit() call, compile it, load it, and run it.
You can insert an exit() call into an "innocent" method using BCEL or similar.
And ...
If there is a debug agent attached to the JVM, the debugger can call exit() on some thread in the JVM.
In short, the answer to your question is Yes.
Your method could be found and invoked dynamically using reflection by any class in the same classloader or any other that is below in the hierarchy.
Also, it has a default access. So it could be invoked statically by any class in the same package.
+1 for #Andres, reflection is one possibility.
Have you tried using a breakpoint on the method and looking at the thread's stacktrace?
Personally I don't use breakpoints (just my style) and would try and look at the thread programmatically. Maybe some of the following code can help you look at the thread and get an idea of what's going on:
public class ThreadUtil {
/** Blocked constructor **/
private ThreadUtil() {
}
/**
* Get the stackstrace of the current {#link Thread}.
* The stacktrace will be returned in the form of a string.
*/
public static String getStackTrace() {
return getStackTrace(Thread.currentThread());
}
/**
* Get the stackstrace of a {#link Thread}.
* The stacktrace will be returned in the form of a string.
*/
public static String getStackTrace(Thread thread) {
StringBuilder sb = new StringBuilder();
StackTraceElement[] currThreadStackTraceElementList = thread.getStackTrace();
appendStackTrace(sb, currThreadStackTraceElementList);
return sb.toString();
}
public static String getAllStackTraces() {
StringBuilder sb = new StringBuilder();
Map<Thread, StackTraceElement[]> threadList = Thread.getAllStackTraces();
for (StackTraceElement[] currThreadStackTraceElementList : threadList.values()) {
appendStackTrace(sb, currThreadStackTraceElementList);
}
return sb.toString();
}
private static void appendStackTrace(StringBuilder sb,
StackTraceElement[] currThreadStackTraceElementList) {
sb.append("Thread stack trace: \n");
for (StackTraceElement currThreadStackTraceElement : currThreadStackTraceElementList) {
sb.append("\t" + currThreadStackTraceElement + "\n");
}
sb.append("\n");
}
}
It's a Processing-specific thing.
void exit() is a method already defined by processing in PApplet.java
As explained in the reference:
Rather than terminating immediately, exit() will cause the sketch to
exit after draw() has completed (or after setup() completes if called
during the setup() function).
For Java programmers, this is not the same as System.exit(). Further,
System.exit() should not be used because closing out an application
while draw() is running may cause a crash (particularly with P3D).
exit() it is expected to be used something like this:
void draw() {
line(mouseX, mouseY, 50, 50);
}
void mousePressed() {
exit();
}
It is called within PApplet.java in a few places, notably in handleKeyEvent to close the sketch when ESC is pressed, or when ⌘w is pressed.
Just rename your method to something other than exit()
I want to suppress the MFC error message on data validation:
void CMotorView::DoDataExchange(CDataExchange* pDX)
{
DDX_Text(pDX, IDC_AMBIENTTEMP, m_pSet->m_AmbientTemp);
}
If the text in editcontrol IDC_AMBIENTTEMP is non numeric on saving data to variables, the framework will show a messagebox prompting the user to enter a number. I want to suppress this message, and handle the error in my own code.
I assumed the framework will throw an exception in case of validation error, but this appears not to be the case. Neither does DDX_Text return a value What am I doing wrong?
void CMotorView::DoDataExchange(CDataExchange* pDX)
{
try
{
DDX_Text(pDX, IDC_AMBIENTTEMP, m_pSet->m_AmbientTemp);
}
catch(CUserException* ex)
{
// nothing caught here
}
catch(...)
{
// nothing caught here either
}
}
In case of an error DDX_Text first displays an error dialog, then it throws an exception. You can catch this with catch(CUserException *e). Please note that a pointer is thrown!
I'd suggest that you either DDX_Text to a string. This does not fail and you can then check if the string is really a number. Or you can write your own DDX_TextMyFn to do what you want. You can use the MFC original function as a base implementation.
Set ES_NUMBER as a style for the edit control. This will reduce errors user can make.
The message boxes inside the DDX routines can't be suppressed or redirected.
Here is some pseudocode that uses a class CEditInt that has a member unction GetValue/SetValue.
You can also write a DDX_EditInt routine that works on a CEdit control and use Get/SetDlgItemInt.
void AFXAPI DDX_EditInt(CDataExchange* pDX, int nIDC, int &iValue)
{
// Get pointer to control
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
CEditInt *pWnd = (CEditInt *)CWnd::FromHandle(hWndCtrl);
// Must be an CEditInt
ASSERT(pWnd->IsKindOf(RUNTIME_CLASS(CEditInt)));
// get the information from the defined window
if (pDX->m_bSaveAndValidate)
// Get the Value
iValue = pWnd->GetValue();
else
pWnd->SetValue(iValue);
}
I am trying to fetch Customer data to parse them into customer object to display on TableView. The following code sometimes works, sometimes not. Whenever it does crash, it shows Customer data is empty in the foreach loop even though I run the same code every time. I do not have clue what could be wrong in this circumstances. I am quite new on this platform. If I am missing anything/ extra information, please let me know.
namespace TableViewExample
{
public partial class MyDataServices : ContentPage
{
private ODataClient mODataClient;
private IEnumerable <IDictionary<string,object>> Customers;
public MyDataServices ()
{
InitializeComponent ();
InitializeDataService ();
GetDataFromOdataService ();
TableView tableView = new TableView{ };
var section = new TableSection ("Customer");
foreach (var customers in Customers) {
//System.Diagnostics.Debug.WriteLine ((string)customers ["ContactName"]);
var name = (string)customers ["ContactName"];
var cell = new TextCell{ Text = name };
section.Add (cell);
}
tableView.Root.Add (section);
Padding = new Thickness (10, 20, 10, 10);
Content = new StackLayout () {
Children = { tableView }
};
}
private void InitializeDataService(){
try {
mODataClient = new ODataClient ("myURL is here");
}
catch {
System.Diagnostics.Debug.WriteLine("ERROR!");
}
}
private void GetDataFromOdataService (){
try {
Customers = mODataClient.For ("Customers").FindEntries ();
}
catch {
System.Diagnostics.Debug.WriteLine("ERROR!");
}
}
}
}
Its hard helping out here, however here are some things to consider:-
It sounds like the dataservice could either be not contactable / offline; too busy or it could even be throwing an exception itself and returning a data response that you are not expecting to receive, that then triggers an exception and crash in your application as your always expecting an exact response without catering for any abnormal responses / events.
If you are contacting an external service over the internet it may just be your internet connection is slow / faulty and not returning the information fast enough as other possibilities.
In your code you are assuming that you always get a response from the server - and that this response will always be of an anticipated structure that your expecting to decode - without factoring in any possibility of abnormal responses returned by the dataservice. I have not used ODataClient personally, so not sure how it behaves in the event of maybe no data received / timeout or in your case the dataservice and how it behaves internally in the response to a bad-request etc.
I am assuming an exception would get thrown, and you do get your debug line executed indicating a failure.
You may want to also adjust this statement so that you write out the exception as well, i.e.:-
private void GetDataFromOdataService ()
{
try
{
Customers = mODataClient.For ("Customers").FindEntries ();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("ERROR!" + ex.ToString());
}
}
If there was a bad response, then the line at Customers = ..... would throw the exception as there may be no Customers returned or some other information packaged in the response from the dataservice.
The Customers variable would also be null at this point I am assuming due to this failing.
So when you get back to your code at foreach (var customers in Customers) { it will then throw a null reference exception as Customers is infact null.
As all your current code executes in the constructor without any try and catch block around this, it will also crash your application at this point as well.
Also you are doing all of this work in the constructor. Try seperating this out. I haven't investigated exactly where the constructor gets called in an iOS page life-cycle, however, if it is in the viewDidLoad, then you have something like 10 seconds for everything to complete, otherwise it will exit automatically. I imagine in your case, this isn't applicable however.
Going forward also try putting your layout controls in the constructor, and move your data task to maybe the OnAppearing override instead.
Using async would definitely be advisable as well, but remember you need to inspect the response from your dataservice, as the error could be embedded within the response also and you will need to detect when it is OK to process the data.
Is there way to handle situation when message is not delivered to server? Dolphin log infors about situation clearly, but I'would like to catch it from code. I was looking for some method like: onError to override like onFinished:
clientDolphin.send(message, new OnFinishedHandlerAdapter() {
#Override
public void onFinished(List<ClientPresentationModel> presentationModels) {
// Do something useful
}
}
});
, but there is nothing like that. Also wrapping send call in try/catch does not work(not suprising since send is not blocking its caller code).
I thing there is definitely some easy way to get informed about undelivered message, but I cant see it.
Thaks, in advace, for answers!
You can assign an onException handler to the ClientConnector - and you are actually supposed to do so. The exception handler will get the exception object passed in that happened in the asynchronous send action.
Below is the default handler that even tells you, what you should do ;-)
Closure onException = { Throwable up ->
def out = new StringWriter()
up.printStackTrace(new PrintWriter(out))
log.severe("onException reached, rethrowing in UI Thread, consider setting ClientConnector.onException\n${out.buffer}")
uiThreadHandler.executeInsideUiThread { throw up } // not sure whether this is a good default
}