Non-existent Notification of Retrying an Action (NNRA)

ECn Categories > Non-Existent Result Notification (NRN) > Non-existent Notification of Retrying an Action (NNRA)

The app does not show any message that indicates that the user should retrying the action.

Amount of Issues App List
8 (A41) Glucosio, (A44) Materialistic - Hacker News, (A48) Tram Hunter, (A49) PocketHub for GitHub

Examples

Tram Hunter

Category: Travel & Local
v 1.7
Scenario: Turn on the internet while try to looking for a route given the vehicle number

The following code snippets show the classes and files that are involved in the generation of the previuos issue.

In order to see how this error is generated, we need to review all the flow event. First, as it can be seen in the video it all starts when the user clicks on “Enter Vehicle Number” option, that event is managed by the “onClickListener” created for the “home_btn_search” button. AS it can be seen when the click event is triggered a new Dialog is created between lines 220 and 223 with the text “Enter Vehicle number” that belongs to the Dialog template. However, at line 223 the listener for the positive button is created and when it is clicked an intent is builted between lines 227 and 229 and triggered ad line 230 into “TramRunActivity”.

app/src/main/java/com/andybotting/tramhunter/activity/HomeActivity.java

    findViewById(R.id.home_btn_search).setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
        	AlertDialog.Builder builder = new AlertDialog.Builder(HomeActivity.this);
        	View view = LayoutInflater.from(builder.getContext()).inflate(R.layout.vehicle_number_dialog, null, false);
        	final EditText editText= (EditText) view.findViewById(R.id.editText);
        	final DialogInterface.OnClickListener positiveListener = new DialogInterface.OnClickListener() {
        		@Override
        		public void onClick(DialogInterface dialog, int which) {
        			try {
        				int vehicleNumber = Integer.parseInt(editText.getText().toString().trim());
228.      				Intent intent = new Intent(HomeActivity.this, TramRunActivity.class);
        				intent.putExtra("vehicleNumber", vehicleNumber);
        				startActivity(intent);

Now that the event flow arrives to the “TramRunActivity” the “onCreate” method is called. At line 158 there is a method call to “displayTramRun” that is in charge of displaying the stops for the tram with the vehicle number that came as an extra with the intent.

app/src/main/java/com/andybotting/tramhunter/activity/TramRunActivity.java

116. public void onCreate(Bundle icicle) {
     ...
158. displayTramRun();

However, this method delegates it responsability to “getTramRun” method at line 310.

app/src/main/java/com/andybotting/tramhunter/activity/TramRunActivity.java

    private void displayTramRun() {
    	mShowDialog = true;
310.	getTramRun();
    }

Now the “getTramRun” method, checks using a variable called “mIsRefreshing” thet there are no more than one refreshing process running at a time. Once the validation is done an asyncTask called “GetTramRun” is created and executed at line 337.

app/src/main/java/com/andybotting/tramhunter/activity/TramRunActivity.java

    private void getTramRun() {
		// Really dumb check that we're not starting two update threads
		// at once.
337.	if (!mIsRefreshing) new GetTramRun().execute();
	}

This asyncTask has 3 important phases. First, the phase called “onPreExecution” that sets correctly the environment for the execution

app/src/main/java/com/andybotting/tramhunter/activity/TramRunActivity.java

private class GetTramRun extends AsyncTask<TramRun, Void, TramRun> {

In this phase, as it can be seen in the following snippet, the variable “mIsRefreshing” is set to true in order to avoid multiple execution at the time.

app/src/main/java/com/andybotting/tramhunter/activity/TramRunActivity.java

    protected void onPreExecute() {
		mIsRefreshing = true;
		if (mShowDialog) showLoadingView(true);
	}   

Second, the main phase called “doInBackground” where the core process is executed. In this case, this method tries to get some imformation related to the vehicle number at line 356. However, due to the connectionless state an error will be generated so the method will fall in the exception clause at line 358 and being the first time it fails it will try again to retrieve the information at line 363. With out any luck, it will fail each time until it try to do it for a nth time that is greatest than an amount setted off for the amounts of available tries. In that case, the method will save the message of the error in the “mErrorMessage” variable.

app/src/main/java/com/andybotting/tramhunter/activity/TramRunActivity.java

    protected TramRun doInBackground(final TramRun... params) {
		if (LOGV) Log.v(TAG, "Fetching getNextPredictedRoutesCollection...");
		try {
			// Get out next trams
			mTramRun = ttService.getNextPredictedArrivalTimeAtStopsForTramNo(mVehicleNumber);
		} catch (TramTrackerServiceException e) {
			// Retry a couple of times before error
			if (mErrorRetry < MAX_ERRORS) {
				mErrorRetry++;
				if (LOGV) Log.e(TAG, "Error " + mErrorRetry + " of " + MAX_ERRORS + ": " + e);
				this.doInBackground(params);
			} else {
				// Save the error message for the toast
366.			mErrorMessage = e.getMessage();
			}
		}
		return mTramRun;
	}

Third, the last phase called “onPostExecute” where the environment is fixed in order to close all open connections and it can be generated a response to the main phase result. Specifically, for this case knowing that an error has been generated, a new message that displays the value of the “dialog_error_fetching” string along with the error message stored from the previous phase.

app/src/main/java/com/andybotting/tramhunter/activity/TramRunActivity.java

    protected void onPostExecute(TramRun tramRun) {
		if (mErrorRetry == MAX_ERRORS) {

			// Toast: Error fetching departure information
			if (mFirstDepartureReqest) {
				final CharSequence message = getString(R.string.dialog_error_fetching, mErrorMessage);
				Toast.makeText(TramRunActivity.this, message, Toast.LENGTH_LONG).show();
			}

Finally, as it can be seen in the following snippet the message displayed to the user do not says that the action must be tried again.

app/src/main/res/values/strings.xml

<string name="dialog_error_fetching">Error fetching departure times (<xliff:g id="error">%1$s</xliff:g>)</string>