Submission failed: JSON didn't validate
5 views (last 30 days)
Show older comments
I am getting the output but it is not being saved into courseera it is showing json didn't validate. Please help me out to solve this problem. Here is my code:
function submitWithConfiguration(conf)
parts = Parts(conf);
fprintf('== Submitting solutions | %s...\n', conf.itemName);
% Get email and token from student
tokenFile = 'token.mat';
if exist(tokenFile, 'file')
load(tokenFile,'token','email');
[email,token] = promptToken(email, token, tokenFile);
else
[email,token] = promptToken('', '', tokenFile);
end
if isempty(token)
fprintf('!! Submission canceled due to empty token. Please try again.\n');
return
end
% Submit assignment
response = submitParts(conf, email, token, parts);
if isfield(response, 'errorCode')
% Construct error message from response
msg = sprintf('!! Submission failed: %s\n', response.errorCode);
if isfield(response,"message")
msg = [msg sprintf('!! %s\n',response.message)];
end
if isfield(response,'details')
if isfield(response.details,'learnerMessage')
msg = [msg sprintf('!! %s\n',response.details.learnerMessage)];
end
end
fprintf(msg);
elseif ~isempty(response)
% Submission successful! Show results to students
showFeedback(parts, response);
save(tokenFile, 'email', 'token');
end
end
%% Helper functions beyond this point
%% promptToken
function [email,token] = promptToken(email, existingToken, tokenFile)
if (~isempty(email) && ~isempty(existingToken))
prompt = sprintf( ...'Use token from last successful submission (%s)? (Y/n): ', ...
email);
reenter = input(prompt, 's');
if (isempty(reenter) || reenter(1) == 'Y' || reenter(1) == 'y')
token = existingToken;
return;
else
delete(tokenFile);
end
end
email = input('Login (email address): ', 's');
token = input('Token: ', 's');
end
%% submitParts
function response = submitParts(conf, email, token, parts)
% Prepare submission
response = '';
submissionUrl = SubmissionUrl(); % Updated
try
body = makePostBody(conf, email, token, parts);
catch ME
fprintf('!! Failed to prepare submission: Error in "%s" (line %d)\n!! %s\n', ...
ME.stack(1).name,ME.stack(1).line,ME.message);
return
end
% Submit assignment
try
responseBody = getResponse(submissionUrl, body);
response = loadjson(responseBody);
catch ME
fprintf('!! Submission failed: Error in "%s" (line %d)\n!! %s\n', ...
ME.stack(1).name,ME.stack(1).line,ME.message);
fprintf('!! Please try again later.\n');
return
end
end
%% getResponse
function response = getResponse(url, body)
% NEW CURL SUBMISSION FOR WINDOWS AND MAC
if ispc
% Regex line will escape double quoted objects to format properly for windows
libcurl
% json_command also has -s option to not print out the progress bar
new_body = regexprep (body, '\"', '\\"');
json_command = sprintf('curl -X POST -s -H "Cache-Control: no-cache" -H "Content-Type: application/json" -d "%s" --ssl-no-revoke "%s"', new_body, url);
else
json_command = sprintf('curl -X POST -H "Cache-Control: no-cache" -H "Content-Type:application/json" -d '' %s '' --ssl-no-revoke ''%s''', body, url);
end
% Run system command
[code, response] = system(json_command);
% test the success code
if (code~=0)
msg = sprintf('Submission with curl was not successful (code = %d)',code);
% Add on the reason for curl failure for common error codes
simpleLookup = {'Unsupported protocol','Failed to initialize','URL malformed', ...
'','Couldn''t resolve proxy','Couldn''t resolve host','Failed to connect to host'};
if any(code == 1:length(simpleLookup))
msg = [msg ': ' simpleLookup{code}];
end
% Throw the error
error(msg);
end
end
%% makePostBody
function body = makePostBody(conf, email, token, parts)
bodyStruct.assignmentSlug = conf.assignmentSlug;
bodyStruct.submitterEmail = email;
bodyStruct.secret = token;
bodyStruct.parts = makePartsStruct(conf, parts);
opt.Compact = 1;
body = savejson('', bodyStruct, opt);
end
%% makePartsStruct
function partsStruct = makePartsStruct(conf, parts)
for part = parts
partId = part{:}.id;
fieldName = makeValidFieldName(partId);
outputStruct.output = conf.output(partId);
partsStruct.(fieldName) = outputStruct;
end
end
%% Parts
function [parts] = Parts(conf) % Updated
parts = {};
for partArray = conf.partArrays
part.id = partArray{:}{1};
part.sourceFiles = partArray{:}{2};
part.name = partArray{:}{3};
parts{end + 1} = part;
end
end
%% showFeedback
function showFeedback(parts, response)
fprintf('== \n');
fprintf('== %43s | %9s | %-s\n', 'Part Name', 'Score', 'Feedback');
fprintf('== %43s | %9s | %-s\n', '---------', '-----', '--------');
evaluation = response.linked.onDemandProgrammingScriptEvaluations_0x2E_v1{1}(1);
for part = parts
% NEW PARSING REPONSE BODY
partEvaluation = evaluation.parts.(makeValidFieldName(part{:}.id));
partFeedback = partEvaluation.feedback;
score = sprintf('%d / %3d', partEvaluation.score, partEvaluation.maxScore);
fprintf('== %43s | %9s | %-s\n', part{:}.name, score, partFeedback);
end
totalScore = sprintf('%d / %d', evaluation.score, evaluation.maxScore);
fprintf('== --------------------------------\n');
fprintf('== %43s | %9s | %-s\n', '', totalScore, '');
fprintf('== \n');
end
%% SubmissionURL
function submissionUrl = SubmissionUrl() % Updated
submissionUrl ='https://www.coursera.org/api/onDemandProgrammingScriptSubmissions.v1?includes=evaluation';
end
1 Comment
Answers (1)
Leepakshi
on 27 Feb 2025
Hey Chethan,
Your code seems correct to me, no issue in that. The error message "JSON didn't validate" indicates that the JSON payload being sent to Coursera's API does not confirm to the expected format. To address this, consider the following steps:
1. Validate JSON Structure: Ensure that the JSON structure constructed in the ‘makePostBody’ and ‘makePartsStruct’ functions aligns with the specifications required by Coursera's API.
2. Inspect JSON Output: Print the JSON body before submission to verify its contents. This can be done by adding a debug statement such as ‘fprintf('JSON Body: %s\n', body);’ to inspect the structure and content.
3. Verify Field Names: Confirm that all field names and their values match the API's requirements. The function ‘makeValidFieldName’ should correctly format these field names.
4. Check API Requirement: Review the API documentation to ensure all necessary fields are included and properly formatted.
5. Escape Special Characters: Ensure that any special characters in the JSON body have correctly escaped, especially on Windows systems, where ‘regexprep’ is utilized for this purpose.
6. Error Details: If additional error details are provided by the API, log these for further insight into the specific validation issues.
7. Manual Testing: Consider using a tool like curl directly from the terminal for manual testing to isolate the issue from the MATLAB environment.
Additional Considerations
- API Changes: If Coursera has updated their API, ensure your code is compatible with the latest version.
- Network Issues: Ensure there are no network issues preventing the request from being sent or received properly.
- MATLAB Version: Ensure you are using a MATLAB version that supports the functions and syntax you are using.
By implementing these steps, you should be able to identify and correct the JSON formatting issue. Let me know if there is anything more I can help with.
Thanks
0 Comments
See Also
Categories
Find more on String Parsing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!