- 
                Notifications
    You must be signed in to change notification settings 
- Fork 0
Feedback #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feedback
Are you sure you want to change the base?
Feedback #1
Conversation
| postCreateDummyJSONUser(i); | ||
| } | ||
| } | ||
|  | 
Check warning
Code scanning / regex
Found trailing whitespace at the end of a line of code. Warning
| }; | ||
| // Serialize the map into a JSON string. | ||
| String contJson = JSON.serialize(contMap); | ||
|  | 
Check warning
Code scanning / regex
Found trailing whitespace at the end of a line of code. Warning
| public with sharing class ContactTriggerHelper { | ||
|  | ||
| public static void checkIds(List<Contact> contacts) { | ||
| List<String> dummyJsonIds = new List<String>(); | ||
| for (Contact cont : contacts) { | ||
| if (cont.DummyJSON_Id__c == null) { | ||
| cont.DummyJSON_Id__c = String.valueOf(Integer.valueOf((math.random() * 100))); | ||
| } | ||
| if (Integer.valueOf(cont.DummyJSON_Id__c) <= 100) { | ||
| dummyJsonIds.add(cont.DummyJSON_Id__c); | ||
| } | ||
| } | ||
| if (!dummyJsonIds.isEmpty()) { | ||
| DummyJSONCallout.getDummyJSONAsync(dummyJsonIds); | ||
| } | ||
| } | ||
|  | ||
|  | ||
| public static void syncUpdate(List<Contact> contacts ) { | ||
| List<Id> contactIds = new List<Id>(); | ||
| for (Contact cont : contacts) { | ||
| if (Integer.valueOf(cont.DummyJSON_Id__c) > 100) { | ||
| contactIds.add(cont.Id); | ||
| } | ||
| } | ||
| if(!contactIds.isEmpty()) { | ||
| DummyJSONCallout.postDummyJsonAsync(contactIds); | ||
| } | ||
| } | ||
| } No newline at end of file | 
Check warning
Code scanning / PMD
Missing ApexDoc comment Warning
| public static void checkIds(List<Contact> contacts) { | ||
| List<String> dummyJsonIds = new List<String>(); | ||
| for (Contact cont : contacts) { | ||
| if (cont.DummyJSON_Id__c == null) { | ||
| cont.DummyJSON_Id__c = String.valueOf(Integer.valueOf((math.random() * 100))); | ||
| } | ||
| if (Integer.valueOf(cont.DummyJSON_Id__c) <= 100) { | ||
| dummyJsonIds.add(cont.DummyJSON_Id__c); | ||
| } | ||
| } | ||
| if (!dummyJsonIds.isEmpty()) { | ||
| DummyJSONCallout.getDummyJSONAsync(dummyJsonIds); | ||
| } | ||
| } | 
Check warning
Code scanning / PMD
Missing ApexDoc comment Warning
| public static void syncUpdate(List<Contact> contacts ) { | ||
| List<Id> contactIds = new List<Id>(); | ||
| for (Contact cont : contacts) { | ||
| if (Integer.valueOf(cont.DummyJSON_Id__c) > 100) { | ||
| contactIds.add(cont.Id); | ||
| } | ||
| } | ||
| if(!contactIds.isEmpty()) { | ||
| DummyJSONCallout.postDummyJsonAsync(contactIds); | ||
| } | ||
| } | 
Check warning
Code scanning / PMD
Missing ApexDoc comment Warning
| public static void getDummyJSONAsync(List<String> JsonIds) { | ||
| for (String j : JsonIds) { | ||
| getDummyJSONUserFromId(j); | ||
| } | ||
| } | 
Check warning
Code scanning / PMD
Missing ApexDoc comment Warning
| // Set the HTTP method to POST. | ||
| postUserRequest.setMethod('POST'); | ||
| // Set the body using generateDummyJsonUserPayload method. | ||
| String contJsonBody = DummyJSONCallout.generateDummyJsonUserPayload(contactId); | 
Check warning
Code scanning / PMD
Variable 'contJsonBody' defined but not used Warning
| Contact contToUpdate = new Contact(); | ||
| contToUpdate.Id = contactId; | ||
| contToUpdate.DummyJSON_Last_Updated__c = Datetime.now(); | ||
| update contToUpdate; | 
Check failure
Code scanning / PMD
Validate CRUD permission before SOQL/DML operation or enforce user mode Error
| update contToUpdate; | ||
| } | ||
| } catch (Exception e) { | ||
| System.debug('Erron on POST to DummyJSON ::: ' + e.getMessage()); | 
Check warning
Code scanning / PMD
Avoid debug statements since they impact on performance Warning
| update contToUpdate; | ||
| } | ||
| } catch (Exception e) { | ||
| System.debug('Erron on POST to DummyJSON ::: ' + e.getMessage()); | 
Check warning
Code scanning / PMD
Calls to System.debug should specify a logging level. Warning
| private static String generateDummyJsonUserPayload(String contactId) { | ||
| // Query the contact to get the field values to generate the JSON payload. | ||
|  | ||
| List<Contact> contList = [SELECT Id, FirstName, LastName, Email, Phone FROM Contact WHERE Id = :contactId]; | 
Check failure
Code scanning / PMD
Validate CRUD permission before SOQL/DML operation or enforce user mode Error
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Adam! 👋
I can see you've put in significant effort on this integrations module - great job on creating a trigger handler class and implementing the HTTP callout patterns! However, there are some critical issues that will prevent your code from working in production that need to be addressed.
What You Did Well ✅
- Excellent separation of concerns by creating the ContactTriggerHelper class
- Good error handling with try-catch blocks
- Proper null checking throughout your code
- Using Named Credentials - great security practice!
- Clean JSON serialization/deserialization logic
Critical Issues That Must Be Fixed 🚨
I've left detailed inline comments, but the main issue is that callouts from triggers require @future annotation. Without this, your code will fail with "Callout from triggers are currently not supported" errors when it runs.
Your Next Steps 🎯
- Add @future(callout=true) to your callout methods
- Fix the missing setBody() call in your POST request
- Add the Content-Type header for your POST request
- Consider bulkification - your current async wrappers will hit governor limits with multiple records
Once you address these issues, your integration will be solid! Feel free to reach out if you have questions about the @future annotation or bulkification patterns.
Keep coding! 💪
| getDummyJSONUserFromId(j); | ||
| } | ||
| } | ||
|  | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚨 Critical Issue: This method needs the @future(callout=true) annotation!
Callouts from triggers are not allowed in Salesforce. When your trigger calls this method, it will fail with:
Callout from triggers are currently not supported
Fix:
@future(callout=true)
public static void getDummyJSONUserFromId(String dummyUserId) {
    // ... rest of your code
}Note: When using @future, all parameters must be primitives (String, Integer, Id, etc.) - no complex objects like Lists of Contacts.
| upsert cont DummyJSON_Id__c; //insert/update from the JSON response using the external id (dummyUserId) | ||
| try { | ||
| HttpRequest userRequest = new HttpRequest(); | ||
| // Set the endpoint URL. Use direct URL or for best practices use Named Credential. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The endpoint URL is missing the user ID! The DummyJSON API expects the ID in the URL path.
It should be:
userRequest.setEndpoint('callout:DummyJsonUser/' + dummyUserId);This way you're calling /users/{id} to get a specific user.
| } | ||
| } | ||
| if (!dummyJsonIds.isEmpty()) { | ||
| DummyJSONCallout.getDummyJSONAsync(dummyJsonIds); | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your getDummyJSONAsync method loops and calls getDummyJSONUserFromId for each ID. Since that method will need @future, you can't call it multiple times in a loop (max 50 @future calls per transaction).
Better approach:
public static void checkIds(List<Contact> contacts) {
    List<String> dummyJsonIds = new List<String>();
    for (Contact cont : contacts) {
        if (cont.DummyJSON_Id__c == null) {
            cont.DummyJSON_Id__c = String.valueOf(Integer.valueOf((math.random() * 100)));
        }
        if (Integer.valueOf(cont.DummyJSON_Id__c) <= 100) {
            dummyJsonIds.add(cont.DummyJSON_Id__c);
        }
    }
    if (!dummyJsonIds.isEmpty()) {
        // Pass the whole list to a SINGLE @future method
        getDummyJSONUsersAsync(JSON.serialize(dummyJsonIds));
    }
}
@future(callout=true)
public static void getDummyJSONUsersAsync(String jsonIds) {
    List<String> ids = (List<String>)JSON.deserialize(jsonIds, List<String>.class);
    // Make one callout for each ID here
}This keeps you within governor limits!
| } | ||
| } | ||
|  | ||
| public static void postCreateDummyJSONUser(String contactId) { | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚨 Critical Issue: Same problem here - this method needs @future(callout=true)!
@future(callout=true)
public static void postCreateDummyJSONUser(String contactId) {
    // ... rest of your code
}| try { | ||
| // Create HTTP request to send. | ||
| HttpRequest postUserRequest = new HttpRequest(); | ||
| // Set the endpoint URL. Use direct URL or for best practices use Named Credential. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing required calls: Your POST request is incomplete! You're generating the JSON payload but never setting it as the request body, and you're missing the Content-Type header.
Add these lines:
postUserRequest.setHeader('Content-Type', 'application/json');
postUserRequest.setBody(contJsonBody);Without setBody(), you're sending an empty POST request!
| cont.Email = (String)responseMap.get('email'); | ||
| cont.Phone = (String)responseMap.get('phone'); | ||
| cont.Birthdate = Date.valueOf((String)responseMap.get('birthDate')); | ||
| // Deserialize the address from the JSON response. | 
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice null checking here! 👍
One small improvement - you could use isEmpty() for the email check too:
cont.Email = String.isBlank(cont.Email) ? 'unknown' : cont.EmailisBlank() checks for both null and empty strings, which is more defensive.
👋! GitHub Classroom created this pull request as a place for your teacher to leave feedback on your work. It will update automatically. Don’t close or merge this pull request, unless you’re instructed to do so by your teacher.
In this pull request, your teacher can leave comments and feedback on your code. Click the Subscribe button to be notified if that happens.
Click the Files changed or Commits tab to see all of the changes pushed to the default branch since the assignment started. Your teacher can see this too.
Notes for teachers
Use this PR to leave feedback. Here are some tips:
For more information about this pull request, read “Leaving assignment feedback in GitHub”.
Subscribed: @Adam-Atoms