I created a trigger that looks like this:
trigger DG_CM_Trigger on CampaignMember (before insert) {
System.debug('DG_CM_Trigger - START');
if (Trigger.isBefore && Trigger.isInsert){
DG_CampaignMember_Class.populateCustomAttributes(trigger.New);
}
System.debug('DG_CM_Trigger - END');
}
As you can see, I have system debug statements at the beginning and end of the trigger. When I look at the debug logs, I can see that the trigger is called...
09:42:46.524 (524616000)|CODE_UNIT_STARTED|[EXTERNAL]|01qc00000004eIV|DG_CM_Trigger on CampaignMember trigger event BeforeInsert for [new]
09:42:46.540 (540035000)|METHOD_ENTRY| [1]|01pc00000006aDT|DG_CampaignMember_Class.DG_CampaignMember_Class()
09:42:46.540 (540101000)|METHOD_EXIT|[1]|DG_CampaignMember_Class
09:42:46.540 (540725000)|METHOD_ENTRY|[4]|01pc00000006aDT|DG_CampaignMember_Class.populateCustomAttributes(LIST<CampaignMember>)
09:42:46.543 (543070000)|CONSTRUCTOR_ENTRY|[114]|01pc00000006aDT|<init>()
09:42:46.543 (543199000)|CONSTRUCTOR_EXIT|[114]|01pc00000006aDT|<init>()
09:42:46.543 (543273000)|METHOD_ENTRY|[114]|01pc00000006aDT|DG_CampaignMember_Class.LeadFieldMapping()
09:42:46.548 (548241000)|METHOD_ENTRY|[41]|01pc00000006aDT|DG_CampaignMember_Class.getCMFieldMapping()
09:42:46.693 (693286000)|METHOD_EXIT|[41]|01pc00000006aDT|DG_CampaignMember_Class.getCMFieldMapping()
09:42:46.703 (703469000)|METHOD_EXIT|[114]|01pc00000006aDT|DG_CampaignMember_Class.LeadFieldMapping()
09:42:46.781 (781457000)|METHOD_EXIT|[4]|01pc00000006aDT|DG_CampaignMember_Class.populateCustomAttributes(LIST<CampaignMember>)
09:42:46.781 (781790000)|CODE_UNIT_FINISHED|DG_CM_Trigger on CampaignMember trigger event BeforeInsert for [new]
However, I do not see my System.debug statement. I had debug statements in the class as well, but does do not show either. I have set the debug log filters to apex code: debug and system: debug (the rest are info). I even tried setting the 'override log filters' on the CampaignMember_Class and also set the levels to apex code: debug and system:debug. I can't seem to figure out why the debug statements are not showing up on the log which is making debugging extremely difficult. Peharps there is some kind of user setting I'm not aware of? User permissions? (although I'm in the admin profile, but I perhaps something in the profile settings that is not set?) Any help would be appreciated.
Try specifying the LoggingLevel as the first parameter to the System.debug calls. E.g.
System.debug(LoggingLevel.Error, 'hello');
Also, if this is a deployed managed package Salesforce will hide all logging.
Related
I am very new to apex, I am trying to understand apex code written by someone else. Its retrieving opportunity data. It gets all the fields except opportunity contact role. Its always empty, even though there is data in it.
It calls the opportunity selector from the service class
Opportunity opp = cq.Opportunities.GetByIdWithOCR(new Set{opportunityId})[0];
in the opportunitySelector.apxc
public List<Opportunity> GetByIdWithOCR(Set<Id> idSet) {
return (List<Opportunity>) GetQueryFactory()
.WithCriteria(cq_Criteria.ValueIn(Opportunity.Id, idSet))
.WithRelatedField(Opportunity.AccountId, Account.Name)
.WithRelatedField(Opportunity.AccountId, Account.BillingStreet)
.WithRelatedField(Opportunity.AccountId, Account.BillingCity)
.WithRelatedField(Opportunity.AccountId, Account.BillingState)
.WithRelatedField(Opportunity.AccountId, Account.BillingPostalCode)
.WithRelatedField(Opportunity.AccountId, Account.BillingCountry)
.WithChildQuery(
cq.OpportunityContactRoles.GetQueryFactory()
.WithCriteria(cq_Criteria.Equals(OpportunityContactRole.Role, 'Decision Maker'))
.WithRelatedField(OpportunityContactRole.ContactId, Contact.Name)
.WithRelatedField(OpportunityContactRole.ContactId, Contact.Phone)
.WithRelatedField(OpportunityContactRole.ContactId, Contact.Email))
.Execute();
}
all the values are there but contact role is empty. Please advice
This is all custom written by your colleague, some attempt at ORM layer. "Normal" apex would be to write the query directly, better performance, some compile-time checks... Hard to say what lurks in that code.
Which community it is? Customer or Partner? Last I checked customer community has no access to Opportunity. Assuming it's Partner - do you know how to check the Profile of the community user and access to whole OpportunityContactRole table and all fields in it?
There are some hacks to let code jump out of the Salesforce security model (without sharing etc) but I wouldn't recommend unless you really know what you're doing and normal ways of controlling data visibility (profiles/permission sets, sharing rules, like sharing sets) failed you.
Try to capture debug logs. Open developer console (if possible, you tagged this as communities) and run your page or experiment with Setup -> Debug Logs. You should be able to find the query and try to execute it manually.
If you want to rule out issues with this query factory try to swap the code with this and see if it's any better:
return [SELECT Account.Name, Account.BillingStreet, Account.BillingCity,
Account.BillingState, Account.BillingPostalCode, Account.BillingCountry,
(SELECT Contact.Name, Contact.Phone, Contact.Email
FROM OpportunityContactRoles
WHERE Role = 'Decision Maker')
FROM Opportunity
WHERE Id IN :idSet];
I'm using QX 5.0.2.
In Build mode, is there a way to (re)activate logs and only show warning+error (log level?)?
Env key 'qx.debug' = true seems to reactivate logs but I can't find the env key for log level (to set it for example to warning).
Thanks in advance.
I think what you're looking for is the static addFilter method, documented at http://www.qooxdoo.org/devel/api/#qx.log.Logger. It lets you filter messages by the class from which they originate, by log level, and on an all-appenders basis or per appender.
Derrell
I am fairly new to powerapps, but it sounds like there is a major limitation on being able to return values for a SQL Server stored procedure.
I have an app that when you push a button pulls data from various controls on screen and submits it to a stored procedure. This is done by invoking a flow. The code is basically :
EditPuddles.Run(ActionDrop.Selected.Value, PuddlesText.Text,
ClassicDrop.Selected.Value, ServiceRates.Text, User().FullName)
The code works and does what it is supposed to. However, what I need now more than anything is it to tell me when it fails or succeeds.
Ideally I would have it return a values that I could use to determine if I should display a success or failure message. I get that I cannot return a data set, but it must at least be able to tell if there is an error.
I'm also new to PowerApps and Power Automate but I figured out a way to show results on success and an error message on failure, after a flow is executed.
PowerApps
For your example the code for the property "OnSelect" of the button should be:
UpdateContext({ PuddlesResult: EditPuddles.Run("a", "b", "c") });
If(
Not IsBlank(PuddlesResult.errormessage),
// on failure:
Notify(PuddlesResult.errormessage, NotificationType.Error, 5000),
// on success: (use PuddlesResult.ResultSets.Table1)
Notify("All good", NotificationType.Information, 5000)
)
Power Automate
Your flow in Power Automate should look like this:
Capture the error message
On error the action "Execute stored procedure (V2)" returns output:
To return the message in the output update the action "Respond to a PowerApp or flow":
Text: ErrorMessage
Expression: outputs('Execute_stored_procedure_(V2)')?['body']?['message']
Return the error message only on failure/timeouts
Select "Configure run after" on the action "Respond to PowerApp or flow":
And set it to only run this action on failure and time outs:
For returning normal results you can use action "Response" and set the "Configure run after" settings to "Is successful".
I hope this helps you and others as it took me a long time too to figure this out. But it will allow you to handle succes and failure appropriately in your PowerApp.
I'm adding BaseX to an existing web application and currently writing code to import data into it. The documentation is crystal-clear that
An existing database will be overwritten.
Finding this behavior mindboggingly dangerous, I tried it with the hope that the documentation was wrong but unfortunately my test confirmed it. For instance, using basexclient I can do this:
> create db test
Database 'test' created in 12.03 ms.
> create db test
Database 'test' created in 32.43 ms.
>
I can also replicate this behavior with the Python client, which is I what I'm actually using for my application. Reducing my code to the essentials:
session = BaseXClient.Session("127.0.0.1", 1984, "admin", "admin")
session.create("test", "")
It does not matter whether test exists or not, the whole thing is overwritten if it exists.
How can I work around this dangerous default behavior? I'd would like to prevent the possibility of missteps in production.
You can issue a list command before you create your database. For instance with the command line client if the database does not exist:
> list foo
Database 'foo' was not found.
Whereas if the database exists:
> list test
Input Path Type Content-Type Size
------------------------------------
This is a database that is empty so it does not show any contents but at least you do not get the error message. When you use a client you have to check whether it errors out or not. With the Python client you could do:
def exists(session, db):
try:
session.execute("list " + db)
except IOError as ex:
if ex.message == "Database '{0}' was not found.".format(db):
return False
raise
return True
The client raises IOError if the server raises an error, which is a very generic way to report a problem. So you have to test the error message to figure out what is going on. We reraise if it happens that the error message is not the one which pertains to our test. This way we don't swallow exceptions caused by unrelated issues.
With that function you could do:
session = BaseXClient.Session("127.0.0.1", 1984, "admin", "admin")
if exists(session, "test"):
raise SomeRelevantException("Oi! You are about to overwrite your database!")
session.create("test", "")
I am attempting to deactivate triggers using the tooling API. I have successfully in a developer ORG. But was unable to do this in a real developer org. Is this a Salesforce tooling api bug?
Here is the basis of the algorithm,
Create a MetadataContainer with a unique Name
save MetadataContainer
Create an ApexTriggerMember setting the Body, MetadataContainerId, ContentEntityId, and Metadata[apiVersion=33.0 packageVersions=[] status="Inactive" urls=nil>]
Modify Metadata["status"]="Inactive"
save ApexTriggerMember
Create/Save ContainerAsyncRequest
monitor container until completed.
display errors if appropriate
In the sandbox, I have confirmed after requerying the Apex enter code hereTriggerMember that the read-only field "Content" looks appropriate. I also confirmed that the MetadataContainerId now points to a ContainerAsyncRequest that has a State of "Completed"
Here are my results, it appears to be a success, but the ApexTrigger is never deactivated
ContentEntityId = 01q.............[The ApexTrigger I want deactivated]
Content="<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<ApexTrigger xmlns=\"urn:metadata.tooling.soap.sforce.com\">
<apiVersion>33.0</apiVersion>
<status>Inactive</status>
</ApexTrigger>"
Metadata={apiVersion=33.0 packageVersions=nil status="Inactive" urls=nil> attributes= {type="ApexTriggerMember"
url="/services/data/v33.0/tooling/sobjects/ ApexTriggerMember/401L0000000DCI8IAO"
}
}
I think you need to deploy the inactive Trigger from Sandbox to Production. You can't simply deactivate the Trigger in Production. This is true even in the UI.
There are other options, such as using a Custom Setting or Metadata Type to store a Run/Don't Run value. You would query that value in the Trigger to decide whether or not to run it.
https://developer.salesforce.com/forums/?id=906F0000000MJM9IAO