-
ChatterFeed
-
0Best Answers
-
0Likes Received
-
0Likes Given
-
5Questions
-
9Replies
Trigger firing in @futuer needs to do callout.
We wrote some custom code that when certain field on the contact are updated, it creates a record in a sync object(SyncLog).
Then there is a trigger that calls a @future method to send that object to an external system. This is required for callouts in triggers.
This is working fine, however we have NPSP installed.
When the address changes it kicks off a address validation process in the @future context. If the address gets validated, it updated the contact and the process creates the SyncLog (still in @future)
At this time we get an error - Future method cannot be called from a future or batch method.
So I figure this out and check for @future and call a method without @future.
Then we getan error
- Http post failed with exception Callout from triggers are currently not supported.
Due to our agreement we are trying to avoid any third party integration utilities.
The callout need to happen in near realtime.
We are caught in a Catch 22. Does anyone have any suggestions?
Here is a diagram of the problem:
Here is the pertinent code.
trigger Code
if (!System.isFuture()) { SVC_SyncLogService.sendSyncLogFuture(new List<ID>(Trigger.newMap.keySet())); } else { SVC_SyncLogService.sendSyncLog(new List<ID>(Trigger.newMap.keySet())); }
SVC_SyncLogService Code
@future (callout=true) public static void sendSyncLogFuture(List<ID> SyncLogList) { try { sendSyncLog(SyncLogList); } catch (Exception e) { {exception code here} } } public static void sendSyncLog(List<ID> SyncLogList) { List<SyncLog__c> SyncLogRecordList = [{select goes here}]; //if running as part of a test class do not call manager if(!Test.isRunningTest()){ {vendorClass} Mgr = new {vendorClass}(); Mgr.sendSyncLog(SyncLogRecordList); } }
- MikeCamp
- April 16, 2020
- Like
- 0
- Continue reading or reply
How do I Assert in a CanvasLifecycleHandler test class
CanvasLifecycleHandler
public class CANV_LIFECYCLE_Registration implements Canvas.CanvasLifecycleHandler { public Set<Canvas.ContextTypeEnum> excludeContextTypes(){ Set<Canvas.ContextTypeEnum> excluded = new Set<Canvas.ContextTypeEnum>(); return excluded; } public void onRender(Canvas.RenderContext renderContext) { Canvas.ApplicationContext app = renderContext.getApplicationContext(); // get urlpath from canvas app string newURL = getURLPath(app.getCanvasUrl()); //add random string to prevent caching newURL += '?R='+ DateTime.now().gettime(); //update the url app.setCanvasUrlPath(newURL); } private string getURLPath(string canvasURL){ String[] URLList = canvasUrl.split('/'); string URLPath = ''; for(Integer a = 3; a < URLList.size(); a++){ URLPath += '/' + URLList[a]; } return URLPath; } }What I have so far for Test Class (strait from docs here (https://developer.salesforce.com/docs/atlas.en-us.platform_connect.meta/platform_connect/canvas_testing_your_canvaslifecyclehandler.htm))
@isTest private class CANV_LIFECYCLE_Registration_TEST { static testMethod void testDefaultMockValues(){ // Test handler using the default mock RenderContext Canvas.Test creates CANV_LIFECYCLE_Registration handler = new CANV_LIFECYCLE_Registration(); Canvas.Test.testCanvasLifecycle(handler,null); } }
- MikeCamp
- November 11, 2015
- Like
- 0
- Continue reading or reply
System.QueryException: Non-selective query against large object type with indexed field (Unique and External ID)
Here is the code
if(!surveyUpdates.isEmpty()){
Map<string,ID> regIDMap = new Map<string,ID>();
for (RP_Registration__c thisReg : [SELECT Id, RPRegistrationID__c from RP_Registration__c
where RPRegistrationID__c in :surveyUpdates]) {
regIDMap.put(thisReg.RPRegistrationID__c,thisReg.ID);
}
//update survey to point registration
for(Survey__c thisSurvey : surveys) {
if(regIDMap.containsKey(thisSurvey.RPRegistrationID__c)){
thisSurvey.Registration__c = regIDMap.get(thisSurvey.RPRegistrationID__c);
}
}
- MikeCamp
- June 16, 2015
- Like
- 0
- Continue reading or reply
Workflow Rule - Outbound Messages Monitoring
Does anyone know of a way to monitor or view a log of the OBM's from my production Org.
We have a WFR that sends a OBM to informatica and on to our mySQL. Randomly the updates are not getting to mySQL and the informatica job does not seem to account for them either. I am trying to figure out if SF is sending them. I have another WFR that has same criteria that does a field update and it is firing.
Tried to get log from SF Support, but they are clueless and then when they finally understood what I was asking for they Sent me to Developer support. They then closed the case because we can't afford Premier Support.
- MikeCamp
- September 05, 2014
- Like
- 0
- Continue reading or reply
Before Trigger giving System.NullPointerException: Attempt to de-reference a null object
I have a fix, but anyone have any ideas why this is happening?
Is my solution the best way to address error?
I have the following trigger giving me an "System.NullPointerException: Attempt to de-reference a null object" error intermittent error on line 28 - newAttendee.Contact__c.addError('This contact is already registered for this event.');
Using test data in a sandbox the trigger works on some and throw exception on others.
Here is an overview of custom objects:
Event
- Registration
- Lookup from Registration to Event
- - Attendee
- - Master detail between Registration and Attendee
- - EventDetail__c is a formula {eventID-contactID}
Here is the trigger
trigger TRG_Attendee_singleContactPerEvent on Attendee__c (before insert, before update) { // Make sure we are not adding a Attendee to the same Event Map<String, Attendee__c> attendeeMap = new Map<String, Attendee__c>(); for (Attendee__C Attendee : System.Trigger.new) { // Only check if adding to an active Registration. if (Attendee.Registration__r.Status__c != 'Canceled') { // Make sure another new Attendee in batch isn't also a duplicate if (attendeeMap.containsKey(Attendee.EventContact__c)) { // If another new Attendee in batch is a duplicate set error Attendee.Contact__c.addError('This contact is already registered for this event.'); } else { // Add to list for check attendeeMap.put(Attendee.EventContact__c, Attendee); } } } // Using a single database query, find all the Attendees in // the database that have the same EventContact as any // of the Attendees being inserted or updated. for (Attendee__C foundAttendee : [SELECT EventContact__c FROM Attendee__c WHERE EventContact__c IN :attendeeMap.KeySet() and Registration_Status__c = 'Active']) { Attendee__C newAttendee = attendeeMap.get(foundAttendee.EventContact__c); newAttendee.Contact__c.addError('This contact is already registered for this event.'); } }
I have fixed by putting if statement around line 27 and 28 like:
if (attendeeMap.containsKey(foundAttendee.EventContact__c)){ Attendee__C newAttendee = attendeeMap.get(foundAttendee.EventContact__c); newAttendee.Contact__c.addError('This contact is already registered for this event.'); }
- MikeCamp
- August 13, 2012
- Like
- 0
- Continue reading or reply
Trigger firing in @futuer needs to do callout.
We wrote some custom code that when certain field on the contact are updated, it creates a record in a sync object(SyncLog).
Then there is a trigger that calls a @future method to send that object to an external system. This is required for callouts in triggers.
This is working fine, however we have NPSP installed.
When the address changes it kicks off a address validation process in the @future context. If the address gets validated, it updated the contact and the process creates the SyncLog (still in @future)
At this time we get an error - Future method cannot be called from a future or batch method.
So I figure this out and check for @future and call a method without @future.
Then we getan error
- Http post failed with exception Callout from triggers are currently not supported.
Due to our agreement we are trying to avoid any third party integration utilities.
The callout need to happen in near realtime.
We are caught in a Catch 22. Does anyone have any suggestions?
Here is a diagram of the problem:
Here is the pertinent code.
trigger Code
if (!System.isFuture()) { SVC_SyncLogService.sendSyncLogFuture(new List<ID>(Trigger.newMap.keySet())); } else { SVC_SyncLogService.sendSyncLog(new List<ID>(Trigger.newMap.keySet())); }
SVC_SyncLogService Code
@future (callout=true) public static void sendSyncLogFuture(List<ID> SyncLogList) { try { sendSyncLog(SyncLogList); } catch (Exception e) { {exception code here} } } public static void sendSyncLog(List<ID> SyncLogList) { List<SyncLog__c> SyncLogRecordList = [{select goes here}]; //if running as part of a test class do not call manager if(!Test.isRunningTest()){ {vendorClass} Mgr = new {vendorClass}(); Mgr.sendSyncLog(SyncLogRecordList); } }
- MikeCamp
- April 16, 2020
- Like
- 0
- Continue reading or reply
How do I Assert in a CanvasLifecycleHandler test class
CanvasLifecycleHandler
public class CANV_LIFECYCLE_Registration implements Canvas.CanvasLifecycleHandler { public Set<Canvas.ContextTypeEnum> excludeContextTypes(){ Set<Canvas.ContextTypeEnum> excluded = new Set<Canvas.ContextTypeEnum>(); return excluded; } public void onRender(Canvas.RenderContext renderContext) { Canvas.ApplicationContext app = renderContext.getApplicationContext(); // get urlpath from canvas app string newURL = getURLPath(app.getCanvasUrl()); //add random string to prevent caching newURL += '?R='+ DateTime.now().gettime(); //update the url app.setCanvasUrlPath(newURL); } private string getURLPath(string canvasURL){ String[] URLList = canvasUrl.split('/'); string URLPath = ''; for(Integer a = 3; a < URLList.size(); a++){ URLPath += '/' + URLList[a]; } return URLPath; } }What I have so far for Test Class (strait from docs here (https://developer.salesforce.com/docs/atlas.en-us.platform_connect.meta/platform_connect/canvas_testing_your_canvaslifecyclehandler.htm))
@isTest private class CANV_LIFECYCLE_Registration_TEST { static testMethod void testDefaultMockValues(){ // Test handler using the default mock RenderContext Canvas.Test creates CANV_LIFECYCLE_Registration handler = new CANV_LIFECYCLE_Registration(); Canvas.Test.testCanvasLifecycle(handler,null); } }
- MikeCamp
- November 11, 2015
- Like
- 0
- Continue reading or reply
System.QueryException: Non-selective query against large object type with indexed field (Unique and External ID)
Here is the code
if(!surveyUpdates.isEmpty()){
Map<string,ID> regIDMap = new Map<string,ID>();
for (RP_Registration__c thisReg : [SELECT Id, RPRegistrationID__c from RP_Registration__c
where RPRegistrationID__c in :surveyUpdates]) {
regIDMap.put(thisReg.RPRegistrationID__c,thisReg.ID);
}
//update survey to point registration
for(Survey__c thisSurvey : surveys) {
if(regIDMap.containsKey(thisSurvey.RPRegistrationID__c)){
thisSurvey.Registration__c = regIDMap.get(thisSurvey.RPRegistrationID__c);
}
}
- MikeCamp
- June 16, 2015
- Like
- 0
- Continue reading or reply
Workflow Rule - Outbound Messages Monitoring
Does anyone know of a way to monitor or view a log of the OBM's from my production Org.
We have a WFR that sends a OBM to informatica and on to our mySQL. Randomly the updates are not getting to mySQL and the informatica job does not seem to account for them either. I am trying to figure out if SF is sending them. I have another WFR that has same criteria that does a field update and it is firing.
Tried to get log from SF Support, but they are clueless and then when they finally understood what I was asking for they Sent me to Developer support. They then closed the case because we can't afford Premier Support.
- MikeCamp
- September 05, 2014
- Like
- 0
- Continue reading or reply
Before Trigger giving System.NullPointerException: Attempt to de-reference a null object
I have a fix, but anyone have any ideas why this is happening?
Is my solution the best way to address error?
I have the following trigger giving me an "System.NullPointerException: Attempt to de-reference a null object" error intermittent error on line 28 - newAttendee.Contact__c.addError('This contact is already registered for this event.');
Using test data in a sandbox the trigger works on some and throw exception on others.
Here is an overview of custom objects:
Event
- Registration
- Lookup from Registration to Event
- - Attendee
- - Master detail between Registration and Attendee
- - EventDetail__c is a formula {eventID-contactID}
Here is the trigger
trigger TRG_Attendee_singleContactPerEvent on Attendee__c (before insert, before update) { // Make sure we are not adding a Attendee to the same Event Map<String, Attendee__c> attendeeMap = new Map<String, Attendee__c>(); for (Attendee__C Attendee : System.Trigger.new) { // Only check if adding to an active Registration. if (Attendee.Registration__r.Status__c != 'Canceled') { // Make sure another new Attendee in batch isn't also a duplicate if (attendeeMap.containsKey(Attendee.EventContact__c)) { // If another new Attendee in batch is a duplicate set error Attendee.Contact__c.addError('This contact is already registered for this event.'); } else { // Add to list for check attendeeMap.put(Attendee.EventContact__c, Attendee); } } } // Using a single database query, find all the Attendees in // the database that have the same EventContact as any // of the Attendees being inserted or updated. for (Attendee__C foundAttendee : [SELECT EventContact__c FROM Attendee__c WHERE EventContact__c IN :attendeeMap.KeySet() and Registration_Status__c = 'Active']) { Attendee__C newAttendee = attendeeMap.get(foundAttendee.EventContact__c); newAttendee.Contact__c.addError('This contact is already registered for this event.'); } }
I have fixed by putting if statement around line 27 and 28 like:
if (attendeeMap.containsKey(foundAttendee.EventContact__c)){ Attendee__C newAttendee = attendeeMap.get(foundAttendee.EventContact__c); newAttendee.Contact__c.addError('This contact is already registered for this event.'); }
- MikeCamp
- August 13, 2012
- Like
- 0
- Continue reading or reply
Batch Apex problems
In several projects, in several orgs, I've scheduled some Batch Apex jobs to run nightly to process large numbers of records. I've run into a couple of problems that are leaving me very uncertain about whether Batch Apex really can handle large jobs.
Every now and then, a job will fail with this error: Unable to write to any of the ACS stores in the alloted time. I first encountered this in September 2010. I filed a Case and created a discussion group posting (http://boards.developerforce.com/t5/Apex-Code-Development/Unable-to-write-to-any-of-the-ACS-stores-in-the-alloted-time/m-p/205908#M36022). After a few weeks, I was finally told that it was an internal issue that had been resolved. After months of running nightly Batch Apex jobs without this problem, it just recurred.
A second issue is that, every now and then, a Batch Apex job gets stuck in the queue in the "Queued" state. When you launch a Batch Apex job, it gets added to the queue in the "Queued" state, and when the system gets around to executing it, the job gets moved to a "Processing" state. Well, I have batch jobs that have been stuck in the "Queued" state since early January. I've had cases open on this problem for over a month, and while the Case finally found its way to Tier 3 Support, there's still no sign of a resolution.
In both cases, the issue is NOT an Apex coding problem. It's an issue with how the platform is queueing and processing Batch Apex jobs.
I'm wondeirng whether anybody else has run into these problems, or other problems executing Batch Apex jobs. What problems have you run into? How have you resolved or worked around them?
Thanks for your insights.
- MJ09
- February 04, 2011
- Like
- 0
- Continue reading or reply