I work with yaws from a docker container for years, basically taken from https://github.com/segeda/docker-yaws/blob/master/Dockerfile:
FROM erlang:20-alpine
...
&& git clone https://github.com/klacke/yaws.git /yaws-src \
...
Things just used to run fine, but all of a sudden my code fails, and I cannot find the error(s). I could not even find a git version which worked when it had before, so I suspect it might not be a code fault, but then -- what could it be?
It cannot be my code, can it? Because I boiled it down to the example given in http://yaws.hyber.org/appmods.yaws and produced the same error:
%% this is my appmod called from yaws
-module(myurl).
-author('kklepper').
-include("../../include/yaws_api.hrl").
%-include("/usr/local/lib/yaws/include/yaws_api.hrl").
% relative or absolute -- either way same result
-export([out/1]).
-define(debug, true).
-ifdef(debug).
-define(trace(Str, X), io:format("Mod:~w line:~w ~p ~p~n",
[?MODULE,?LINE, Str, X])).
-else.
-define(trace(X, Y), true).
-endif.
box(Str) ->
{'div',[{class,"box"}],
{pre,[],Str}}.
out(A) ->
?trace('A', A),
{ehtml,
[{p,[],
box(io_lib:format("A#arg.appmoddata = ~p~n"
"A#arg.appmod_prepath = ~p~n"
"A#arg.querydata = ~p~n",
[A#arg.appmoddata,
A#arg.appmod_prepath,
A#arg.querydata]))}]}.
The file yaws_api.hrl was and still is present:
/yaws # ls -la /usr/local/lib/yaws/include/yaws_api.hrl
-rw-r--r-- 1 1000 50 5563 May 13 2018 /usr/local/lib/yaws/include/yaws_api.hrl
With trace you can see that the A record is not correct -- no A#arg.querydata etc. -- hence the error. Why?
Obviously, querydata, for example, as such is given: lg=en.
Mod:myurl line:22 'A' {arg,#Port<0.2934>,
{{10,255,0,2},52801},
{headers,"keep-alive",
"text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, image/apng, */*;q=0.8, application/signed-exchange;v=b3",
"voxx.b2d",undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36",
undefined,[],undefined,undefined,undefined,
undefined,undefined,undefined,undefined,
undefined,
[{http_header,11,'Accept-Language',undefined,
"de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7"},
{http_header,10,'Accept-Encoding',undefined,
"gzip, deflate"},
{http_header,0,"Upgrade-Insecure-Requests",
undefined,"1"}]},
{http_request,'GET',
{abs_path,"/industries?lg=en"},
{1,1}},
{http_request,'GET',
{abs_path,"/industries?lg=en"},
{1,1}},
undefined,"/industries","lg=en","industries","/ci",
"/","/ci/industries",undefined,undefined,<0.163.0>,
[],[],[],"/industries",myurl}
=ERROR REPORT==== 4-Oct-2019::00:46:06 ===
ERROR erlang code threw an uncaught exception:
File: appmod:0
Class: error
Exception: {badrecord,arg}
Req: {http_request,'GET',{abs_path,"/industries?lg=en"},{1,1}}
Stack: [{myurl,out,1,
[{file,"/usr/local/lib/yaws/voxx/ebin/myurl.erl"},{line,29}]},
{yaws_server,deliver_dyn_part,8,
[{file,"yaws_server.erl"},{line,2921}]},
{yaws_server,aloop,4,[{file,"yaws_server.erl"},{line,1274}]},
{yaws_server,acceptor0,2,[{file,"yaws_server.erl"},{line,1073}]},
{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,247}]}]
By now I ran out of ideas. Any hint?
The data in question seems to be there. I am interested among others in language data and used to get the accepted language from A like so:
get_lang(A) ->
find_lang(find_http_header('Accept-Language', (A#arg.headers)#headers.other)).
find_http_header(Key,Headers) when is_list(Headers) ->
case lists:keysearch(Key,3,Headers) of
{value,{_,_,_,_,Value}} -> Value;
false -> undefined
end.
find_lang(AcceptLanguage) ->
case AcceptLanguage of
undefined ->
"en";
_ ->
L = lists:nth(1,string:tokens(
lists:nth(1,string:tokens(
lists:nth(1,string:tokens(AcceptLanguage, ";"))
,","))
,"-")),
L
end.
Without the correct data structure, this cannot work.
A detail you included in your question shows that your appmod is getting a badrecord exception when trying to access the #arg record that Yaws passes to it. There are a couple ways to get such an exception:
Pass an instance of a data type other than the expected record type to the function. This isn't happening in this case, since Yaws is calling the function and is correctly passing an #arg record instance.
Compile the caller and the called function with two different definitions of the same record. We can simulate this problem in an Erlang shell as follows:
First, define a record #arg containing two fields
Define a function that takes an instance of that record as an argument and returns the value of one of the fields
Redefine the record in the shell to have just one field
Pass an instance of the redefined record to the function, which will cause a badrecord exception
1> rd(arg, {f,g}).
arg
2> F = fun(A) -> A#arg.f end.
#Fun<erl_eval.7.126501267>
3> rd(arg, {f}).
arg
4> F(#arg{f=1}).
** exception error: {badrecord,arg}
Since you're using Yaws 2.0.7 and you're also cloning Yaws from github, it's likely you're compiling some part of your code, probably your appmod, against the Yaws master branch and then running it against 2.0.7. Sometime after I tagged Yaws 2.0.7 on github, I accepted a change that added a new field to the #arg record definition. What this means is that any #arg record Yaws 2.0.7 creates and passes to your appmod will result in a badrecord exception since the appmod expects a record containing the additional field.
I can think of a few ways to avoid this problem:
Get rid of your Yaws github clone and build everything against your installation of Yaws 2.0.7.
In your Yaws clone, git checkout yaws-2.0.7 so that anything you access or use from the clone is the same as what's in your Yaws 2.0.7 installation.
Uninstall Yaws 2.0.7, then compile and install from your Yaws clone. Perhaps apply a local tag first, then build and install from that, so that your deployments can be more easily reproduced, and so that you can grab Yaws updates from github without breaking anything locally.
I have a F# fake script which works with Nuge.Core to extract package files. If I try to do this with c# console app everything works properly. However if I execute exactly the same script in a f# fake script it is not working. There are so many dependencies here and I have no idea where to look for a help: docker.dotnet, fake, f#, nuget.core
To reproduce this you need to download Docker.DotNet.2.124.3.nupkg
For the c# sample you need console application and to install nuget.core nuget package. This is working!
class Program
{
static void Main()
{
var zip = new NuGet.ZipPackage(#"Docker.DotNet.2.124.3.nupkg");
foreach (var file in zip.GetFiles())
{
System.Console.WriteLine(file.Path);
}
}
}
For the f# sample you need these two files side by side:
https://gist.github.com/mynkow/e6f0e550fcacc268dd1e9b743e17d344
ERROR:
==============================================================================
FsiEvaluationException:
Error: System.InvalidOperationException: 'NETStandard.Library' already has a dependency defined for 'Microsoft.NETCore.Platforms'.
at NuGet.Manifest.ValidateDependencySets(IPackageMetadata metadata)
at NuGet.Manifest.Validate(Manifest manifest)
at NuGet.Manifest.ReadFrom(Stream stream, IPropertyProvider propertyProvider, Boolean validateSchema)
at NuGet.LocalPackage.ReadManifest(Stream manifestStream)
at NuGet.ZipPackage.EnsureManifest(Func`1 manifestStreamFactory)
at NuGet.ZipPackage..ctor(String filePath, Boolean enableCaching)
at <StartupCode$FSI_0005>.$FSI_0005_Test$fsx.main#() in C:\Users\mynkow\Desktop\Reproduce\test.fsx:line 12
Stopped due to error
Output: [Loading C:\Users\mynkow\Desktop\Reproduce\test.fsx]
==============================================================================
Input: C:\Users\mynkow\Desktop\Reproduce\test.fsx
\Arguments:
C:\fsi.exe
Exception: Yaaf.FSharp.Scripting.FsiEvaluationException: Error while compiling or executing fsharp snippet. ---> System.Exception: Operation failed. The error text has been print the error stream. To return the corresponding FSharpErrorInfo use the EvalInteractionNonThrowing, EvalScriptNonThrowing or EvalExpressionNonThrowing
at Microsoft.FSharp.Compiler.Interactive.Shell.FsiEvaluationSession.commitResult[a,b](FSharpChoice`2 res)
at Microsoft.FSharp.Compiler.Interactive.Shell.FsiEvaluationSession.EvalScript(String filePath)
at Yaaf.FSharp.Scripting.Helper.evalScript#1303.Invoke(String arg00) in C:\code\FAKE\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1303
at Yaaf.FSharp.Scripting.Helper.save_#1276-2.Invoke(Unit unitVar0) in C:\code\FAKE\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1277
at Yaaf.FSharp.Scripting.Helper.consoleCapture[a](TextWriter out, TextWriter err, FSharpFunc`2 f) in C:\code\FAKE\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1221
at Yaaf.FSharp.Scripting.Helper.redirectOut#1247[a](Boolean preventStdOut, OutStreamHelper out, OutStreamHelper err, FSharpFunc`2 f) in C:\code\FAKE\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1254
at Yaaf.FSharp.Scripting.Helper.save_#1275-1.Invoke(String text) in C:\code\FAKE\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1276
--- End of inner exception stack trace ---
at Yaaf.FSharp.Scripting.Helper.save_#1275-1.Invoke(String text) in C:\code\FAKE\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1284
at Yaaf.FSharp.Scripting.Helper.session#1306.Yaaf-FSharp-Scripting-IFsiSession-EvalScriptWithOutput(String ) in C:\code\FAKE\paket-files\matthid\Yaaf.FSharp.Scripting\src\source\Yaaf.FSharp.Scripting\YaafFSharpScripting.fs:line 1308
at Fake.FSIHelper.runScriptUncached(Boolean useCache, String scriptPath, IEnumerable`1 fsiOptions, Boolean printDetails, CacheInfo cacheInfo, TextWriter out, TextWriter err) in C:\code\FAKE\src\app\FakeLib\FSIHelper.fs:line 471
System.InvalidOperationException: 'NETStandard.Library' already has a dependency defined for 'Microsoft.NETCore.Platforms'.
at NuGet.Manifest.ValidateDependencySets(IPackageMetadata metadata)
at NuGet.Manifest.Validate(Manifest manifest)
at NuGet.Manifest.ReadFrom(Stream stream, IPropertyProvider propertyProvider, Boolean validateSchema)
at NuGet.LocalPackage.ReadManifest(Stream manifestStream)
at NuGet.ZipPackage.EnsureManifest(Func`1 manifestStreamFactory)
at NuGet.ZipPackage..ctor(String filePath, Boolean enableCaching)
at <StartupCode$FSI_0005>.$FSI_0005_Test$fsx.main#() in C:\Users\mynkow\Desktop\Reproduce\test.fsx:line 12
Stopped due to error
I have tried with the 5 latest versions of all possible dependencies and the results are exactly the same => c# is working, f# is not. Do you have any clue or just anything which you can advise me to try to fix this?
DIRTY SOLUTION:
This is how the Docker.DotNet.2.124.3.nupkg looks like inside
If I remove for example the netstandard1.6 everything works. This means that the problem is in nuget.core, right? But why it is working in c# console app? No idea!
UPDATE: I am able to execute properly the code from F# console application
I've downloaded the packages with paket, and changed the script this way:
#r #"./packages/FAKE/tools/FakeLib.dll"
#r #"./packages/NuGet.Core/lib/net40-Client/NuGet.Core.dll"
open System
open System.Collections.Generic
open System.IO
open Fake
Target "Test" (fun _ ->
printfn "=============================================================================="
global.NuGet.ZipPackage(#"Docker.DotNet.2.124.3.nupkg").GetFiles() |> Seq.iter(fun x -> printfn "%s" x.Path )
)
RunParameterTargetOrDefault "target" "test"
It gives this
Microsoft (R) F# Interactive version 14.0.23413.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
For help type #help;;
>
--> Referenced 'C:\tmp\visualfsharp.issue.nuget\./packages/FAKE/tools/FakeLib.dll'
--> Referenced 'C:\tmp\visualfsharp.issue.nuget\./packages/NuGet.Core/lib/net40-Client/NuGet.Core.dll'
Building project with version: LocalBuild
Shortened DependencyGraph for Target Test:
<== Test
The resulting target order is:
- Test
Starting Target: Test
==============================================================================
Running build failed.
Error:
System.InvalidOperationException: The schema version of 'Docker.DotNet' is incompatible with version 1.6.30117.9648 of NuGet. Please upgrade NuGet to the latest version from http://go.microsoft.com/fwlink/?LinkId=213942.
at NuGet.Manifest.CheckSchemaVersion(XDocument document)
at NuGet.Manifest.ValidateManifestSchema(XDocument document, String schemaNamespace)
at NuGet.Manifest.ReadFrom(Stream stream, IPropertyProvider propertyProvider)
at NuGet.ZipPackage.EnsureManifest()
at FSI_0002.clo#9.Invoke(Unit _arg1) in C:\tmp\visualfsharp.issue.nuget\test.fsx:line 11
at Fake.TargetHelper.runSingleTarget(TargetTemplate`1 target) in C:\code\FAKE\src\app\FakeLib\TargetHelper.fs:line 493
---------------------------------------------------------------------
Build Time Report
No target was successfully completed
---------------------------------------------------------------------
---------------------------------------------------------------------
val it : unit = ()
>
The version of NuGet.Core is 2.12, and I'm seeing it is referencing Microsoft.Web.Xdt which is not loaded.
Maybe you can achieve what you want by simply using paket and adding Docker.DotNet as a dependency, it will extract it for you.
If you have reproducible error that you described, please make a zip and post an issue to visualfsharp repository.
I'm trying to use FAKE to build my F# project.
The build.fsx looks like below and works fine.
#r "packages/FAKE/tools/FakeLib.dll"
open Fake
Target "Default" (fun _ ->
trace "Hello World from FAKE"
)
RunTargetOrDefault "Default"
Then I want to use fsc from FAKE. Following the official tutorial, I added one line open Fake.FscHelper and get below error message:
#r "packages/FAKE/tools/FakeLib.dll"
open Fake
open Fake.FscHelper
// this value is not a function and can not be applied
// union case FscParam.Target: TargetType -> FscParam
Target "Default" (fun _ ->
~~~~~~~~~~~~~~~~
trace "Hello World from FAKE"
)
RunTargetOrDefault "Default"
I appreciate if anyone can give me any advice.
I'm using VS Code on Mac with Mono 4.2.1.
And my paket.lock looks like below:
NUGET
remote: https://www.nuget.org/api/v2
specs:
FAKE (4.21.0)
FSharp.Core (4.0.0.1)
FsUnit (2.0.0)
FSharp.Core (>= 3.1.2.5)
NUnit (3.0.1)
NUnit (3.0.1)
This happens because the module FscHelper defines a constructor called Target (see source), and that constructor conflicts with the Target function from the TargetHelper module. There is an issue filed about it.
Until the issue is fixed, there are three ways to work around this ambiguity:
Don't open FscHelper, just use all its innards in a qualified manner (e.g. FscHelper.Compile etc.)
Re-alias the TargetHelper.Target function in the local scope:
open Fake
open Fake.FscHelper
let Target = TargetHelper.Target
Target "Default" (fun _ ->
trace "Hello World from FAKE"
)
Reorder the open statements:
open Fake.FscHelper
open Fake
And since you're using this helper, note that the documentation for it is outdated. In particular, the Fsc task is deprecated in favor of the Compile task (see source).
Change the order of the open statements
#r #"packages/FAKE/tools/FakeLib.dll"
open Fake.FscHelper
open Fake
Target "a" (fun _ ->
["a.fs"] |> Compile []
The order of your open statements determines the precedence of the name resolution with the later opened modules and namespaces taking precedent.
If I have:
import demo::lang::Exp::Concrete::WithLayout::Syntax;
if ((Exp)`<IntegerLiteral e> + <IntegerLiteral e>` := (Exp)`5 + 6`) {
println(e);
}
This prints 6. Is this a possible bug or a design decision, e.g. because of performance considerations? It should of course not print anything, since e cannot be matched to both 5 and 6. This is, however, in contrast to matching with ADTs, where this is caught, i.e.:
data ExpNum = numb(int n) | add(ExpNum e1, ExpNum e2);
if (add(numb(x), numb(x)) := add(numb(5), numb(6))) { println(x); }
Will not print a number, while it does print a number when using numb(5) instead of numb(6).
Ps. I ran the example both from Rascal source using Eclipse Plug-in Development (using a forked version merged with the latest version of Rascal), as well as on two machines using the official Eclipse plugin. The plugin, however, returned the following on both machines:
|stdin:///|(4,46,<1,4>,<1,50>): Java compilation failed due to with classpath [/home/wouter/eclipse//plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar]: package org.eclipse.imp.pdb.facts.type does not exist
The reason why I am asking is because, somewhat similarly, ConcreteListVariablePattern automatically throws a RedeclaredVariable-exception without checking if the match result's value is equivalent to the variable in the environment, in contrast to e.g. QualifiedNamePattern which checks if the result is equivalent to the value in the environment in case of a readily declared variable.
Thank you!
This is definitely a bug: the variable e is declared twice (without warning), the match succeeds and the binding to second e is printed.
Expected behavior would be that a RedeclaredVariable exception is thrown.
A work around is as follows:
if ((Exp)`<IntegerLiteral e1> + <IntegerLiteral e2>` := (Exp)`5 + 6` && e1 == e2) {
println(e1);
}