Closed rolandleth closed 7 months ago
Thank you for opening this issue!
🔔 @tmwrnr @irangarcia you might want to have a look.
I have an extension published too, and I don't always reply in time, but the built-in (old) Reminders function worked and got deprecated in favour of this one and can not be installed anymore (or at least I can't find out how), a decent time to reply would be immensely appreciated, especially for an extension so core like this...
Hey @rolandleth, sorry for the late reply. We'll investigate this bug. Thanks for reporting the issue and for your patience! 😊
Hello! Is there anything I could help with? I really miss this extension, I used to use it multiple times per day 🙁
Hey @rolandleth, we've added an update that should make the error more descriptive. Could you test it out again and let me know if you see more than SwiftError
?
If that's not the case, could you follow these instructions:
Show Build in Finder
create-reminder.js
in a text editor and search for Could not get any data
. If you can't find it, that means the extension probably hasn't been updated.Hey, @thomaslombart! Sorry for the late reply.
I just uninstalled and reinstalled it, to make sure it's the latest version, but the error is almost the same. I see no "Show Build in Finder" action command.
I did find the extension on disk and create-reminder.js
still contains Could not get any data
, even though I just reinstalled it. Uninstalling does delete the folder, so installing again doesn't reuse anything old.
SwiftError: Could not get any data
at ChildProcess.<anonymous> (/Users/<user>/.config/raycast/extensions/112ad714-bf10-4ccc-a70f-4232bb2241a5/my-reminders.js:50:13560)
at ChildProcess.emit (node:events:514:28)
at ChildProcess.emit (node:domain:488:12)
at maybeClose (node:internal/child_process:1105:16)
at ChildProcess._handle.onexit (node:internal/child_process:305:5)
Not sure if a screenshot with create-reminder.js
helps in any way, but here it is:
@thomaslombart Seeing how the "legacy" extension worked just fine and this issue isn't getting any love, would it at least be possible to get the legacy extension back?
Agreed with @ddotlic. This extension is completely broken and there seems to be no timeline for a fix. Quickly adding reminders is one of my primary use cases for Raycast, so re-enabling the legacy extension should be done as a workaround until this extension can be given the attention needed to resolve this issue.
If it helps the debugging process, the error seems to be coming from this component. I don't have enough familiarity with these APIs to suggest a fix, but the least we can do is review the included fields for availability, and wrap that return
in an error-catching block.
The extension isn't "completely broken" - it seems that, for a handful of users, the extension can't execute a binary to get the data from Apple's APIs. We haven't been able to reproduce nor find any pattern as to when and why it would fail.
Let's see if we can find some common points between the failing setups:
ls -la ~/.config/raycast/extensions/112ad714-bf10-4ccc-a70f-4232bb2241a5/assets/compiled_raycast_swift
in a terminal and send the result?~/.config/raycast/extensions/112ad714-bf10-4ccc-a70f-4232bb2241a5/assets/compiled_raycast_swift/AppleReminders
in a terminal and send the result?@mathieudutour I agree that framing "completely broken" is likely a personal feeling and not based in hard data (I did not make this statement BTW) but I also suspect that "handful of users" is similarly misguided - as a (professional, making a living of it) developer myself, I occasionally get user-supplied bug reports (large web site with lots of users) which when found turn out to be years old. Why didn't we get any other bug reports about it (again, lots of users, public site, financial industry, not something silly)? I assume because it doesn't hurt the users enough or they don't know how to file a bug report or are too busy or...
But this philosophical point aside, I am extremely happy that you've given us things to try. Here's my report:
Protection
is completely disabled).rw-r--r--@ 904k draza 12 Feb 14:42 AppleReminders
AppleReminders
since it's obviously not an executableBased on 3 and 4, I manually made the file executable running (while in the plugin folder) chmod 755 AppleReminders
which did not help, followed by a more dangerous chmod 777 AppleReminders
which also did not help. In both cases, I did quit and reopen Raycast.
If there's anything else I could try, please LMK and I'll gladly do it. Thanks!
Forgot to say: now that AppleReminders
can be executed, when I do so I get back Not enough Command-Line arguments
.
I tried figuring out the arguments from the my-reminders.js
but as it's minified, it's very hard to do so.
Running ls command produces .rw-r--r--@ 904k draza 12 Feb 14:42 AppleReminders Cannot run the AppleReminders since it's obviously not an executable
That's interesting! Now that the file is executable, the extension still shows the same error?
The code we use to run the binary is fairly simple:
import { join } from "path";
import { chmod } from "fs/promises";
import { spawn } from "child_process";
async function runSwiftFunction(command, ...args) {
// the path below is dynamically generated
const swiftPath = "~/.config/raycast/extensions/112ad714-bf10-4ccc-a70f-4232bb2241a5/assets/compiled_raycast_swift/AppleReminders";
await chmod(swiftPath, "755");
return new Promise((resolve, reject) => {
const commandArgs = [command];
for (const arg of args) {
try {
commandArgs.push(JSON.stringify(arg, (k, v) => v === undefined ? null : v));
} catch (err) {
reject(new SwiftError("Failed to serialize input to JSON: " + err.message));
return;
}
}
const child = spawn(swiftPath, commandArgs);
const stdout = [];
const stderr = [];
child.stdout?.on("data", (data) => {
stdout.push(data.toString());
});
child.stderr?.on("data", (data) => {
stderr.push(data.toString());
});
child.on("exit", (code) => {
if (code === 0) {
try {
const result = stdout.join("").trim();
if (result.length != 0) {
resolve(JSON.parse(result));
} else {
resolve(null);
}
} catch (err) {
const error = new SwiftError("Failed to deserialize result from JSON: " + err.message);
error.stdout = stdout.join("").trim();
error.stderr = stderr.join("").trim();
reject(error);
}
} else {
const error = new SwiftError(stderr.join("").trim() || stdout.join("").trim() || "Could not get any data");
error.stdout = stdout.join("").trim();
error.stderr = stderr.join("").trim();
reject(error);
}
});
child.on("error", (error) => {
reject(error);
});
});
}
export class SwiftError extends Error {
constructor(message) {
super(message);
this.name = "SwiftError";
}
}
That's interesting! Now that the file is executable, the extension still shows the same error?
@mathieudutour Yes, still the same error. I noticed the chmod
in the script, this obviously did nothing prior.
What are the arguments sent to this, when one wants to list reminders? I'd like to try executing this manually.
I noticed the
chmod
in the script, this obviously did nothing prior.
Yes this is weird indeed
~/.config/raycast/extensions/112ad714-bf10-4ccc-a70f-4232bb2241a5/assets/compiled_raycast_swift/AppleReminders getReminders
should return a big JSON
should return a big JSON
It returns zsh: trace trap ./AppleReminders getReminders
I ran this from iTerm
(latest) where it also has access to Reminders. Tried again from Apple's own Terminal
same thing.
Oh 👀
Could you try running the Color Picker
extension? Do you get the same issue?
Could you try running the Color Picker extension? Do you get the same issue?
Not only does this extension work just fine, but I was not aware of it yet I need that kind of functionality fairly often, thanks for pointing it out! 🎉
I guess this is technically not good news WRT Reminders
extension, is there anything else I could try?
So it means that it's not something related to the swift/js bridge, but something related to the swift code itself. I'll see what we can do - but that was already a big help, we made some progress, thanks!
@mathieudutour I am not familiar enough with Swift nor native development on a mac, though I've done decades of native development on Windows - I presume you can "catch an exception" (seems that this isn't strictly the correct term, but close enough) during the execution and then trace the details to the console? You can send me the executable without the need to publish the new version of the plugin.
Alternatively, if the source is accessible, I can try to run this in debug mode from XCode? Again, haven't done much in this regard, but "how hard could it be" 😉
The source is indeed accessible here: https://github.com/raycast/extensions/tree/main/extensions/apple-reminders/swift/AppleReminders
@ddotlic, do other commands fail for you, like Create Reminder
? @rolandleth reported that lists couldn't be loaded in this command.
@thomaslombart So, the Create Reminder
technically works, but the lists picker is empty, where I actually have one list and put all my reminders to that list.
OK, so I was bored and tried the good old print debugging
- the Swift code works fine up to the line
remindersData = reminders.map { $0.toStruct() }
where it crashes. I tried using try/catch
but my Swift skills are pathetic, so I got nothing.
The code is able to get necessary permission and the app does see all of my (mostly already completed) reminders (1563
of them to be exact).
LMK if I can try something else.
Since the build is "obfuscated" by the use of wrappers over wrappers etc (not judging), I cannot figure out (yet) how to build the Swift part in debug mode.
You can find the toStruct
function of the EKReminder
extension in the EventKit+Additions.swift
file. I'm wondering if it's not the toStruct
function of the EKCalendar
extension that's bugging. Could you comment this line and let me know if:
remindersData = reminders.map { $0.toStruct() }
still crashes?
Otherwise, you could try to set up some breakpoints in the code to see if it's ever reached and see the content of the different variables:
https://github.com/raycast/extensions/assets/16003285/a25e70ac-006f-4b55-8950-2ab8c0e9c043
@thomaslombart Thanks for your patience. I am actually debugging like an idiot, by sprinkling print
statements over the codebase.
Unfortunately, when I comment out the line you pointed at, the build fails. Since I'm running the build from the command line using npm run build
what I get back is fairly useless (no details about the error).
How did you open just AppleReminders
in XCode?
No worries! 😄
Opening extensions/apple-reminders/swift/AppleReminders
from Xcode should be enough.
https://github.com/raycast/extensions/assets/16003285/e0976043-d659-4bdb-9bcb-ffbb1da26eb1
@thomaslombart Duh! OK, now we're "cooking with gas" or as we Europeans should probably say "cooking with induction" 😛
I can now debug normally - the error I had previously was when commenting out the line you indicated, I commented out the closing parenthesis 🤦♂️. Btw, that by itself does nothing.
The issue is index out of bounds at the most unexpected place, month index is 12 at some point, I need to debug this more to tell you more, but we're getting somewhere!
@thomaslombart This appears to be a classic off-by-one: the Apple docs for the monthsOfTheYear
state that values range from 1 to 12, where the code assumes array index, 0 to 11.
The offending line is this one.
In theory, using monthSymbols?[$0.intValue - 1]
should do the trick: indeed it does, after this change all my reminders are printed as a large JSON string.
I patched my local copy and everything works fine now, including the fetching of the default list in the Create Reminder
UI.
If possible, it would likely speed things up to filter out completed tasks, since they don't seem to be shown anywhere in Raycast's UI (nor would I ever expect them to, personally).
Oh, that's interesting. So, it means it's crashing for some recurring reminders? Could you share some of your reminders so that I can reproduce it as well?
As for the completed reminders, they're loaded upfront so that you can display them if you want (as shown below). Does it have a noticeable performance impact if you filter them out?
Anyway, thanks a lot for investigating this. It's really helpful! 🙌
Could you share some of your reminders so that I can reproduce it as well?
@thomaslombart I am not sure how I would go about "sharing my own reminders" but this particular one is just a yearly reminder, every 4th Friday of December (details unimportant).
I thought my comments were clear - the code assumes 0 based month indices, where the Apple uses 1 based month indices, you must have seen this kind of misunderstanding a million times, no?
My reminder being for December, its "index" is 12, out of bounds of a typical month array with 12 entries, last one having an index of 11. I pointed at the line exactly in my comment above and provided the fix - just subtract one.
I took a deeper look at that and if you run it locally, you get a much more helpful error:
SwiftError: Swift/ContiguousArrayBuffer.swift:600: Fatal error: Index out of range
Instead of just:
SwiftError: Could not get any data
So there's two issues here. The first one is the Apple Reminders one that I'll fix in the following hours thanks to you. The second one has to do with how we're sending the errors in production. We'll follow up on that so that if we have other errors in the future, it'll be way easier to identify the cause.
Anyway, thanks again for your help. I'll ship the PR soon 🙌
Awesome, can confirm it now works, thank you!
Extension
https://raycast.com/raycast/apple-reminders
Description
Error:
Steps To Reproduce
Open
My Reminders
(privacy permissions granted).Current Behaviour
Nothing loads, error.
Expected Behaviour
To load.
Extra info
Creating reminders works (although lists do not load in that view).