Setting tabs not loading - Unexpected end of JSON

Hi all,

Update: I realized that in my local, the content-type response type is application/json for the tabs, while in staging is text/html. That could be the culprit, but even forcing nginx to send application json is not working. It might be that OJS send specifics content types via header() function, ehich overwrites the web server rule?

Some days ago we deployed OJS to a docker/kubernetes server. Everything went well except that, when going to Settings → Journal (Where Masthead, Contact & Sections tabs are), none of them loads, with the message in Chrome JS console VM4010:1 Uncaught SyntaxError: Unexpected end of JSON input.

The reason of that is that the jsonString variable passed to $.pkp.controllers.TabHandler.prototype.dataFilter method in TabHandler.js is empty (""), hence the error thrown in that method.

Debugging a bit, by following the execution of:

  1. JournalSettingsTabHandler and then
  2. ManagerSettingsTabHandler and finnaly in
  3. SettingsTabHandler::showTab($args, $request) method

Good, in this method is when the first problem arises: if ($this->_isValidTab()) { simply returns false, and instead of doing/acting accordingly, the method silently finishes without returning or logging anything, and then the JS error finishes the execution for good.

Going deeply into the code, var dumping methods:

function _isValidTab() {

Returns the following:
array(3) {
[“masthead”]=> string(51) “”
[“contact”]=> string(57) “”
[“sections”]=> string(45) “controllers/tab/settings/journal/sections.tpl”

So, the issue that brings to this problem is that the current tab is not set.

Finally, the last debug step I could thought was to go to, the base class where variables are set and debug $_this->_requestVars array to see if the :

array(1) { [“k”]=> string(1) “0” }
array(1) { [“k”]=> string(1) “0” }
array(1) { [“k”]=> string(1) “0” }

While in localhost the same variable correctly has:

array(2) {
[“tab”] => string(8) “masthead”
["_"] => string(13) “1558014894862”

After this, I have no idea why the tab variables are not loaded, nor where to continue my debug to see the reason. Any idea would be appreciated.

OJS Version:

PS: I read this post but it didn’t help sadly, and besides that, I’d like to know the reason why that happened, rather than a full wipe out of the code :slight_smile:
PS2: Sorry the long post, tried to be as detailed as possible.

Hi @Jose_Ares,

Looks like It’s related to: JSON Issues after Installing Plugins
(Although there isn’t any solution yet).

What jsonString variable contains? Is it a valid JSON?

Hi @Vitaliy,

thanks for your help. I’ll read that post. In the meantime, jsonString is coming empty (""), hence $.parseJson function fails I guess.

Btw, I’m working in the Update comment I posted, that means, try to change the content-type of the response, as for some reason when deployed onto that server is text/html instead of application/json (And as the HTML template is returned as a json string, it could be the culprit)

Have no idea why it can happen. Google tells that text/html response may be due to extra whitespaces before opening PHP tag or after closing (if they are still anywhere in the code). Or there is something wrong with Nginx configuration. @NateWr and @asmecher probably know more.

Hi @Jose_Ares,

Are you sure you’re using the exact same code on both systems? There were recent changes that made OJS more consistent about setting the content type headers (JSON responses do not consistently set content-type to application/json · Issue #3944 · pkp/pkp-lib · GitHub); it should be resolved at least partially in 3.1.1-4 and certainly in 3.1.2.

Alec Smecher
Public Knowledge Project Team

Hi @asmecher, thanks for your help.

Yes, the code is the same both locally and in staging.

Regarding the commit you talked about, it’s from 2018, so we have it (I checked CustomBlockGridHandler with the latest commit you posted and they are the same)

I was wondering that I can’t find the specific file in the codebase where the content type for this tabs are set. If you can help me out with that, I can add another round of debugging to try to figure it out.

We’re trying to see the server side, checking what content type is set in the web server, but for now to no avail.

Thanks and regards, Jose

Hi @Jose_Ares,

When a handler returns a JSONMessage object, that’s noticed in the PKPRouter::_authorizeInitializeAndCallRequest function that invoked the handler. Here’s the (current) code that does this:

// Return the result of the operation to the client.
if (is_string($result)) echo $result;
elseif (is_a($result, 'JSONMessage')) {
    header('Content-Type: application/json');
    echo $result->getString();

Alec Smecher
Public Knowledge Project Team

Hi @asmecher,

I saw that piece of code and debugged it. Sadly, the if/else lacks one detail, which is the case when there is nor a string nor a JSONMessage. In my case (If I remember correctly), returns null, so this code silently fails without any logs (That’s maybe the reason why when you asked several times if PHP error log has some data, all the users answered No), it’s just because the OJS team didn’t take in account the default case (Maybe thinking that it should never happen, but is does)

Regards, Jose

Hi @Jose_Ares,

The Handler function is intended to either output its own content/headers (e.g. the file download code does this), or to pass back a string or a JSONMessage for the calling code to send to the end user. What is the case you’re running into, where a null is returned but the Handler expects the calling code to do something?

Alec Smecher
Public Knowledge Project Team

Hi @Alec, thanks a lot for the quick answer :slight_smile:

Thing is, your last question is exactly my very problem :), I have no idea why it’s the value it is (Again, I removed the var dumps in the server, so it will take a bit, let me debug again). It’s quite obvious that there’s something wrong when returning a response, but as far as I remember, I could get to the point of var_dump($_GET) in

		$_this =& PKPRequest::_checkThis();
                var_dump($_this->_requestVars); //This returns something wrong, which was posted in the description :)
		if (!isset($_this->_requestVars)) {
			$_this->_requestVars = array_merge($_GET, $_POST);
		return $_this->_requestVars;

So, it's the piece of code I posted in the original question :slight_smile: